税务智眸api
首页
登录产品
登录产品
  • test
  • test
发票产品
发票产品
  • test
  • test
申报产品
申报产品
  • test
  • test
首页
登录产品
登录产品
  • test
  • test
发票产品
发票产品
  • test
  • test
申报产品
申报产品
  • test
  • test
  1. 快速开始
  • 基本介绍
  • 快速开始
    • 对接指引
    • 接口调用
    • 调用模式
    • SDK集成
  • 平台接口鉴权
    • 认证鉴权简介
  • 登录业务
    • 简介
  • 中间号业务
    • 中间号申请流程及常见问题
  • 发票业务
  • 申报业务
  1. 快速开始

接口调用

本文档面向调用方:说明如何构造加密请求、计算签名、解析加密响应,以及常见错误排查。
各语言的完整调用示例见 第 7 节。

1. 概述#

传输安全:业务明文使用国密 SM4 / CBC / ZeroPadding 加密后,以 Base64 密文形式放在报文字段中传输。
身份认证:appKey 标识调用方,appSecret 既用作 SM4 密钥,也参与签名计算。
完整性:sign 对关键字段做 MD5 签名,防止报文被篡改。
双向加密:响应体中的业务数据同样是密文,调用方需用本次请求的 IV 解密。
双层响应:响应是双层 code / msg / data / success,外层为网关层校验、内层为业务层结果;内层成功后取内层的 data,为明文。
报文格式:支持 JSON 与 application/x-www-form-urlencoded,字段名完全相同。

2. 接入准备#

请先向平台申请并确认以下信息:
项目说明
接口地址域名 https://itax.jcsk100.com/,具体路径如 https://itax.jcsk100.com/{业务接口路径}
appKey调用方唯一标识
appSecret必须为 16 字节,既是 SM4 密钥,也是签名要素
version版本号,按平台约定填写(示例 1.0)
appSecret 长度不是 16 字节会直接导致加解密失败,务必确认。

3. 请求规范#

3.1 基本约定#

项目值
请求方式POST(推荐)
Content-Typeapplication/json(或 application/x-www-form-urlencoded)
字符编码UTF-8

3.2 请求字段#

字段类型必填说明
appKeyString是调用方标识
encryptStrString是业务明文的 SM4 密文,Base64 编码,无换行
ivString是本次请求的初始向量,Base64 编码的 16 字节随机值
timestampString是时间戳字符串,例:1690000000000
versionString是版本号
signString是签名,见 3.3
密文字段名默认为 encryptStr,如平台另有约定,以平台通知为准。

3.3 签名规则#

sign = MD5( appKey + appSecret + encryptStr + timestamp + iv )
拼接顺序固定,各字符串之间无任何分隔符。
使用 UTF-8 字节参与 MD5 计算。
输出 32 位小写十六进制字符串。
注意:参与签名的 iv 是 Base64 字符串本身(与报文中完全一致),不是原始字节。

3.4 加解密规则#

项目值
算法SM4
模式CBC
填充ZeroPadding(零字节填充,不是 PKCS5/PKCS7)
密钥 keyappSecret 的原始字节(16 字节,UTF-8)
初始向量 iv每次请求随机生成的 16 字节,Base64 后放入 iv 字段
明文编码UTF-8
密文编码Base64(去掉换行)
加密步骤
1.
生成 16 字节随机 IV,Base64 编码得到 iv。
2.
业务明文(JSON 字符串,UTF-8)经 SM4/CBC/ZeroPadding 加密后 Base64 编码,得到 encryptStr。
3.
按 3.3 计算 sign。
4.
组装 JSON 报文发送。
解密响应
1.
解析响应体,先判断外层(网关层) 的 code / success。
2.
外层通过后,取出外层的 data(Base64 密文)。
3.
使用本次请求的 key 与 IV 做 SM4/CBC/ZeroPadding 解密,得到内层(业务层) 的 JSON,形如 {"code":200,"msg":"...","data":{...},"success":true}。
4.
再判断内层的 code / success,内层成功后取内层的 data,该 data 为明文(不再加密),直接按接口清单取字段即可。
调用方必须在发起请求时保存该次 IV,用于响应解密。

3.5 报文示例#

请求报文:
{
  "appKey": "your_app_key",
  "encryptStr": "8Jq2F0n3mZ8kQy1vX0k8wZq7b9Rf4hT2sYq1n7Vb3xM=",
  "iv": "MTIzNDU2Nzg5MDEyMzQ1Ng==",
  "timestamp": "1690000000000",
  "version": "1.0",
  "sign": "3f2a9c1d0b8e7f6a5d4c3b2a19081726"
}
业务明文(加密前):
{
  "lsh": "2026091400001"
}

4. 响应规范#

响应是双层 code / msg / data / success 结构:
外层(网关层):由网关做参数、appKey、签名等校验,其 data 是 SM4 密文(Base64)。
内层(业务层):外层 data 解密后得到的 JSON,才是真正的业务结果,其 data 是明文业务数据(不再加密)。

4.1 外层(网关层)#

{
  "code": 200,
  "msg": "处理成功",
  "data": "base64密文",
  "success": true
}
字段类型说明
codeint200 表示网关层校验通过,其他为网关层失败
msgString网关层提示信息
dataString内层(业务层)结果的 SM4 密文(Base64),外层成功时存在
successboolean网关层是否成功

4.2 内层(业务层)#

外层 data 用本次请求的 key / IV 解密后得到:
{
  "code": 200,
  "msg": "处理成功",
  "data": {
    "lsh": "2026091400001",
    "status": "1"
  },
  "success": true
}
字段类型说明
codeint200 表示业务层处理成功,其他为业务失败
msgString业务层提示信息(失败时为具体原因)
dataObject / Array明文业务数据,内层成功时存在,按接口清单取字段
successboolean业务层是否成功

4.3 处理流程#

HTTP 响应体
  └─ 外层 code/msg/data/success        ← 网关层校验
       ├─ 外层失败(code ≠ 200)→ 直接用外层 msg 报错,data 一般为空,无需解密
       └─ 外层成功(code = 200)→ 取外层 data 解密
            └─ 内层 code/msg/data/success   ← 业务层结果
                 ├─ 内层失败(code ≠ 200)→ 用内层 msg 报错
                 └─ 内层成功(code = 200)→ 取内层 data(明文)使用
必须两层都判断:外层通过只代表网关放行了请求,业务是否成功要看内层 code。
外层失败时不要尝试解密(没有 data 或 data 不是密文)。
内层 data 是明文,不需要、也不能再做解密。
服务端异常也以 HTTP 200 + code 返回,请以响应体 code 判断成败,不要只看 HTTP 状态码。

5. 错误码#

错误码分属两层,排查时先看是哪一层报出的。

5.1 网关层(外层)#

codemsg说明 / 排查方向
400核心参数为空,请检查appKey / encryptStr / iv / timestamp / version / sign 有缺失,核对报文
400未找到匹配的对接方信息appKey 错误或未开通,核对 appKey
400数据验签失败,请检查签名拼接顺序、大小写、编码有误,或字段被改动
400租户越权传入的 tenantId 不在授权范围内
500其他异常信息如 iv 非法、密钥长度不符、解密失败等,按 msg 排查
网关层失败时不会返回密文 data,不要解密。

5.2 业务层(内层)#

codemsg说明 / 排查方向
200处理成功取内层 data(明文)使用
其他具体业务原因由各业务接口自行定义,按内层 msg 排查,并以接口清单为准
业务层错误码与含义按接口清单为准,此处仅说明通用约定。

6. 注意事项与常见问题#

0.
响应是双层结构,外层是网关层、内层是业务层,两层都要判断 code,内层成功后取内层的 data(明文),详见第 4 节。
1.
IV 每次请求都要随机生成,不要复用;响应解密必须使用同一 IV,请务必保存。
2.
appSecret 必须为 16 字节,否则 SM4 初始化失败。
3.
iv 必填,且必须是合法的 Base64(16 字节)。
4.
填充方式为 ZeroPadding,不是 PKCS5/PKCS7,跨语言实现时尤其注意。
5.
签名中的 iv 使用 Base64 字符串本身,不是解码后的字节。
6.
明文业务参数名需与接口清单中定义的参数名完全一致,否则字段会被忽略。
7.
报文中的 appKey、timestamp、sign 等协议字段以协议层为准,业务明文中无需重复传递。
8.
按租户维度调用时,需在业务明文中显式传入 tenantId(是否需要传递以平台说明为准)。
9.
建议在发起请求前对 sign、iv、encryptStr 做空值与长度校验,减少无效请求。
10.
建议设置合理的连接/读取超时,并对失败响应做日志留痕,便于与平台侧对账排查。

7. 调用示例#

通用要点:
密钥 appSecret 与 IV 均为 16 字节,每次请求随机生成 IV。
算法组合为 SM4 / CBC / ZeroPadding,Base64 输出需去掉换行。
签名是固定的拼接串 MD5:appKey + appSecret + encryptStr + timestamp + iv。
响应为双层结构:外层 data 用同一组 key / IV 解密得到内层(业务层)JSON;两层都要判断 code,内层成功后取内层的 data(明文)。
无现成 SM4 库的语言,需自行实现 SM4-CBC 无填充 + 手动零填充(明文不足 16 字节整数倍补 0x00,解密后去掉尾部 0x00)。
明文长度恰好为 16 字节整数倍时不要再补一整块,这一点与 PKCS7 不同,是最容易出错的地方。
Python 使用 gmssl 时不要直接用 crypt_cbc()(内部强制 PKCS7 填充),参见 7.2 Python。
Go 无内置 SM4 且无内置 ZeroPadding,需手写填充/去填充,参见 7.3 Go。
C# 使用 Portable.BouncyCastle 时不要使用 PaddedBufferedBlockCipher + ZeroBytePadding(16 字节对齐时会多补一块),参见 7.4 C#。
各语言 ZeroPadding 实现对照见 第 8 节。

7.1 Java#

依赖:cn.hutool:hutool-all(SM4)、com.alibaba:fastjson(JSON)。
调用:

7.2 Python#

依赖:pip install gmssl requests(gmssl 提供 SM4 算法,requests 发送 HTTP)。
重要:gmssl 的 crypt_cbc() 在加密时会强制做 PKCS7 填充,与本协议的 ZeroPadding 不一致,不能直接调用。
下面的示例用「ECB 单块运算 + 手动 CBC 链 + 手动零填充」实现,已与服务端(Java hutool SM4/CBC/ZeroPadding)做过逐字节对拍验证(含明文长度恰好为 16 倍数的边界场景)。
调用:
关键点说明:
项说明
_zero_pad不足 16 字节补 b"\x00";长度已对齐时不补额外块,否则服务端会解出多余字节
decrypt解密后 rstrip(b"\x00") 去掉零填充
padding_mode=_NO_PADDING绕开 gmssl 默认的 PKCS7 填充,让 crypt_ecb() 只做单块运算
secrets.token_bytes(16)每次请求生成随机 IV,不可复用
ensure_ascii=False业务明文含中文时使用,编码统一 UTF-8

7.3 Go#

依赖:github.com/tjfoc/gmsm(提供 SM4 Block 实现),CBC 用标准库 crypto/cipher 组装,零填充自行处理。
Go 语言无内置 SM4,不要指望任何库替你做 ZeroPadding:多数库默认 PKCS7。示例中的 zeroPad() 在长度已对齐时不补额外的块,务必照搬。
调用:

7.4 C##

依赖:Portable.BouncyCastle(提供 SM4 引擎),HTTP 用 HttpClient。
重要:不要使用 PaddedBufferedBlockCipher + ZeroBytePadding。实测它在明文长度恰好为 16 字节整数倍时会多补一整块(比 Java 侧多 16 字节密文),导致服务端解密出现多余字节。
正确写法是 BufferedBlockCipher(无填充)+ 手动零填充,示例已按此实现并与服务端对拍通过。
调用:
HttpClient 建议按单例复用(示例已用静态实例),勿每条请求创建。

8. 各语言 ZeroPadding 实现对照#

ZeroPadding 是最容易出错的环节,四种语言的关键实现对比:
语言库 / 依赖推荐做法已验证的坑
Javahutool-allnew SM4(Mode.CBC, Padding.ZeroPadding, key, iv)与服务端同源,无坑
PythongmsslECB 单块 + 手动 CBC 链 + 手动零填充crypt_cbc() 强制 PKCS7 填充,不可直接用
Gogithub.com/tjfoc/gmsm/sm4其 cipher.Block 实现 + 标准库 crypto/cipher CBC + 手动零填充无任何内置填充,需自己 pad/unpad
C#Portable.BouncyCastleBufferedBlockCipher + 手动零填充PaddedBufferedBlockCipher + ZeroBytePadding 在 16 字节对齐时多补一整块
统一规则:明文不足 16 字节倍数时补 0x00;恰好为倍数时不补额外块;解密后必须去掉尾部 0x00。
以上四种语言的示例均与服务端(Java hutool SM4/CBC/ZeroPadding)做过密文逐字节对拍,覆盖非对齐、16 字节对齐、含中文三类场景。
修改于 2026-09-14 07:45:50
上一页
对接指引
下一页
调用模式
Built with