跳转到内容

消息签名

SHA 签名规则

报文 Header 中的 Signature 字段是对报文 Body 内容的签名。 以 Payment 接口为例:

第一步:构造待签名字符串

在计算签名结果之前,接入方需要构造一个待签名的字符串。

TIP

将 HTTP method、Request URL、DateTime、Key、MsgID 和 HTTP Body 按固定顺序用换行符 (\n) 连接起来,得到待签名字符串.

按照以下方法构造的待签名的字符串,待签名的字符串有 6 行。每行都包含一个参数并以换行符结尾(最后一行没有换行符)。如果一行为空,则该行将不存在,并且不需要换行符。

换行符:\n(ASCII 码值为 0x0A)

待签名字符串参数描述
HTTP methodPOST/GET/PUT/DELETE
Request URL请求路径+查询参数字符串。不包含 URL 的域名部分。
DateTime请求发送的时间。与请求 Header 中的 DateTime 一致。
Key由 EVO Cloud 分配的签名密钥。
MsgID消息 ID。与请求 Header 中的 MsgID 一致。
HTTP body您要在请求报文 Body 中发送的所有参数。

下面是一个构建完成的待签名字符串的样例

json
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 请求报文:

curl
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 中的签名结果进行验签,验签流程如下:

  1. 构造待签名字符串,方法与签名时一致。
  2. 对待签名字符串进行哈希值计算,使用的算法与您请求时的算法一致。
  3. 将第 2 步的结果与报文 Header 中的 Authorization 进行对比,如果一致则为验签成功。

国密签名规则

报文 Header 中的 Signature 字段是对报文 Body 内容的签名。 以 Payment 接口为例:

密钥使用规则

在使用国密算法进行签名时,需要用到两对 SM2 密钥对,其中一对由 EVO Cloud 生成,另一对由您生成。在密钥生成后,相互共享公钥。

密钥使用规则收单机构 -> EVO CLoudEVO 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 methodPOST/GET/PUT/DELETE
Request URL请求路径+查询参数字符串。不包含 URL 的域名部分。
DateTime请求发送的时间。与请求 Header 中的 DateTime 一致。
MsgID消息 ID。与请求 Header 中的 MsgID 一致。
HTTP body您要在请求报文 Body 中发送的所有参数。

INFO

下面是一个构建完成的待签名字符串的样例

json
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 请求报文:

curl
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 中的签名结果进行验签,验签流程如下:

  1. 构造待签名字符串,方法与签名时一致。
  2. 计算待签名字符串的摘要,方法与签名时一致。
  3. 使用 EVO Cloud 提供的公钥对报文 Header 中 Authorization 字段中的签名信息进行解密。
  4. 对比 2、3 两步中的结果,如果一致则为验签成功。