消息签名
SHA 签名规则
报文 Header 中的 Signature
字段是对报文 Body 内容的签名。 以 Payment
接口为例:
第一步:构造待签名字符串
在计算签名结果之前,接入方需要构造一个待签名的字符串。
TIP
将 HTTP method、Request URL、DateTime、Key、MsgID 和 HTTP Body 按固定顺序用换行符 (\n) 连接起来,得到待签名字符串.
按照以下方法构造的待签名的字符串,待签名的字符串有 6 行。每行都包含一个参数并以换行符结尾(最后一行没有换行符)。如果一行为空,则该行将不存在,并且不需要换行符。
换行符:\n(ASCII 码值为 0x0A)
待签名字符串参数 | 描述 |
---|---|
HTTP method | POST/GET/PUT/DELETE |
Request URL | 请求路径+查询参数字符串。不包含 URL 的域名部分。 |
DateTime | 请求发送的时间。与请求 Header 中的 DateTime 一致。 |
Key | 由 EVO Cloud 分配的签名密钥。 |
MsgID | 消息 ID。与请求 Header 中的 MsgID 一致。 |
HTTP body | 您要在请求报文 Body 中发送的所有参数。 |
下面是一个构建完成的待签名字符串的样例
POST
/g2/v0/payment/acq/10130014/evo.offline.payment
20240305175825+0800
NeTQlv6okyBmbelQP1RujxYmnp0S4GtA
M20240305175825926
{"merchantTransInfo":{"merchantTransID":"T20240305175317143","merchantTransTime":"2024-03-05T17:53:17+08:00"},"paymentMethod":{"type":"card","card":{"posEntryMode":"manual","pinFlag":false,"termReadability":"5","cardInfo":{"cardNumber":"4761340000000043"}}},"transAmount":{"currency":"HKD","value":"1.00"},"autoCapture":false,"pspInfo":{"mcc":"5499","sponsorCode":"441378","merchantID":"202106305812001","terminalID":"00000001","merchantName":"Test","storeID":"202106305812001","storeName":"Test Store","street":"Test street","city":"MYS","postCode":"202000","nation":"MYS"}}
第二步:计算签名密文
使用 SHA256 或 SHA512 计算待签名字符串的哈希值。将得到哈希值作为签名值。例如,使用 SHA256 对第一步中的待签名字符串进行签名,得到的签名值为 `c0696645edb9f8413dcd458892cbcf9143ecd3fbde8a16c4d46d2f95e65ee4b2
第三步:将签名放入 HTTP 请求的 Header 中
将 HTTP Header 中的 SignType
设置为您使用的签名算法,将 Authorization
设置为第二步中计算得到的签名值,最终得到最终要发送的 HTTP 请求报文:
POST /g2/v0/payment/acq/10130014/evo.offline.payment HTTP/1.1
Host: {EVO_Cloud_DOMAIN_NAME.com}
DateTime: 20240305175825+0800
MsgID: M20240305175825926
SignType: SHA256
Authorization: c0696645edb9f8413dcd458892cbcf9143ecd3fbde8a16c4d46d2f95e65ee4b2
Content-Type: application/json
{"merchantTransInfo":{"merchantTransID":"T20240305175317143","merchantTransTime":"2024-03-05T17:53:17+08:00"},"paymentMethod":{"type":"card","card":{"posEntryMode":"manual","pinFlag":false,"termReadability":"5","cardInfo":{"cardNumber":"4761340000000043"}}},"transAmount":{"currency":"HKD","value":"1.00"},"autoCapture":false,"pspInfo":{"mcc":"5499","sponsorCode":"441378","merchantID":"202106305812001","terminalID":"00000001","merchantName":"Test","storeID":"202106305812001","storeName":"Test Store","street":"Test street","city":"MYS","postCode":"202000","nation":"MYS"}}
验签规则
当您收到来自 EVO Cloud 的应答或异步通知时,建议您对报文 Header 中的签名结果进行验签,验签流程如下:
- 构造待签名字符串,方法与签名时一致。
- 对待签名字符串进行哈希值计算,使用的算法与您请求时的算法一致。
- 将第 2 步的结果与报文 Header 中的
Authorization
进行对比,如果一致则为验签成功。
国密签名规则
报文 Header 中的 Signature
字段是对报文 Body 内容的签名。 以 Payment
接口为例:
密钥使用规则
在使用国密算法进行签名时,需要用到两对 SM2 密钥对,其中一对由 EVO Cloud 生成,另一对由您生成。在密钥生成后,相互共享公钥。
密钥使用规则 | 收单机构 -> EVO CLoud | EVO CLoud -> 收单机构 |
---|---|---|
签名 | 机构的私钥(机构自行生成并保存) | EVO CLoud 的私钥(EVO CLoud 自行生成并保存) |
验签 | 机构的公钥(机构自行生成并线下交互给 EVO CLoud) | EVO CLoud 的公钥(EVO CLoud 自行生成并并线下交互给机构) |
TIP
密钥格式私钥:64 个字符(0-9,A-F),不区分大小写公钥:128 个字符(0-9,A-F),不区分大小写
第一步:构造待签名字符串
在计算签名结果之前,接入方需要构造一个待签名的字符串。
TIP
将 HTTP method、Request URL、DateTime、MsgID 和 HTTP Body 按固定顺序用换行符 (\n) 连接起来,得到待签名字符串.
按照以下方法构造的待签名的字符串,待签名的字符串有 5 行。每行都包含一个参数并以换行符结尾(最后一行没有换行符)。如果一行为空,则该行将不存在,并且不需要换行符。
换行符:\n(ASCII 码值为 0x0A)
待签名字符串参数 | 描述 |
---|---|
HTTP method | POST/GET/PUT/DELETE |
Request URL | 请求路径+查询参数字符串。不包含 URL 的域名部分。 |
DateTime | 请求发送的时间。与请求 Header 中的 DateTime 一致。 |
MsgID | 消息 ID。与请求 Header 中的 MsgID 一致。 |
HTTP body | 您要在请求报文 Body 中发送的所有参数。 |
INFO
下面是一个构建完成的待签名字符串的样例
POST
/g2/v0/payment/acq/10130014/evo.offline.payment
20240305175825+0800
M20240305175825926
{"merchantTransInfo":{"merchantTransID":"T20240305175317143","merchantTransTime":"2024-03-05T17:53:17+08:00"},"paymentMethod":{"type":"card","card":{"posEntryMode":"manual","pinFlag":false,"termReadability":"5","cardInfo":{"cardNumber":"4761340000000043"}}},"transAmount":{"currency":"HKD","value":"1.00"},"autoCapture":false,"pspInfo":{"mcc":"5499","sponsorCode":"441378","merchantID":"202106305812001","terminalID":"00000001","merchantName":"Test","storeID":"202106305812001","storeName":"Test Store","street":"Test street","city":"MYS","postCode":"202000","nation":"MYS"}}
第二步:计算摘要
使用 SM3 算法计算待签名字符串的摘要,将得到的摘要用于下一步的签名。
计算后得到的摘要为:10DC4ACE369A0F56FE44A2A352E35494FDD749D70D61034FF0C5D16DD0E15C50
第三步:计算签名
使用 SM2 算法对第二步中得到的摘要进行签名,假设私钥为:769cdff9cc8b28365a99d61213c13e03d304a1c5c1e8e78343c5e983f82f94d7
签名后得到签名结果为:8362a0a7f35c27541508de8cc51e4aee62a8c8dd072966cee498e36df1ff9f042d5a60137bb058b26e1b57da04e9bed4a3c091d3227dbc8e5a815d249f47430b
(每次计算签名结果时签名结果不同)
第四步:将签名放入 HTTP 请求的 Header 中
将 HTTP Header 中的 SignType
设置为您使用的签名算法,将 Authorization
设置为第三步中计算得到的签名值,最终得到最终要发送的 HTTP 请求报文:
POST /g2/v0/payment/acq/10130014/evo.offline.payment HTTP/1.1
Host: {EVO_Cloud_DOMAIN_NAME.com}
DateTime: 20240305175825+0800
MsgID: M20240305175825926
SignType: SM2withSM3
Authorization: 8362a0a7f35c27541508de8cc51e4aee62a8c8dd072966cee498e36df1ff9f042d5a60137bb058b26e1b57da04e9bed4a3c091d3227dbc8e5a815d249f47430b
Content-Type: application/json
{"merchantTransInfo":{"merchantTransID":"T20240305175317143","merchantTransTime":"2024-03-05T17:53:17+08:00"},"paymentMethod":{"type":"card","card":{"posEntryMode":"manual","pinFlag":false,"termReadability":"5","cardInfo":{"cardNumber":"4761340000000043"}}},"transAmount":{"currency":"HKD","value":"1.00"},"autoCapture":false,"pspInfo":{"mcc":"5499","sponsorCode":"441378","merchantID":"202106305812001","terminalID":"00000001","merchantName":"Test","storeID":"202106305812001","storeName":"Test Store","street":"Test street","city":"MYS","postCode":"202000","nation":"MYS"}}
验签规则
当您收到来自 EVO Cloud 的应答或异步通知时,建议您对报文 Header 中的签名结果进行验签,验签流程如下:
- 构造待签名字符串,方法与签名时一致。
- 计算待签名字符串的摘要,方法与签名时一致。
- 使用 EVO Cloud 提供的公钥对报文 Header 中
Authorization
字段中的签名信息进行解密。 - 对比 2、3 两步中的结果,如果一致则为验签成功。