跳转到内容

PIN 加密 ​

PIN 加密 ​

对于线下带密码的卡交易,在传输密码的时候需要对密码进行加密后传输,EVO Payment 支持 DUKPT 加密算法以及国密 SM4 加密算法。

DUKPT 加密规则 ​

EVO Payment 支持使用 DUKPT(ANSI X9.24)加密算法对 PIN 进行加密。

密钥使用规则 ​

在使用 DUKPT 算法对 PIN 进行加密时,您需要先生成一个 BDK 然后配置在 EVO Payment 系统中。

第一步:获取 IPEK ​

使用 BDK 和 KSN(EC=0)生成 IPEK

假设

BDK 为:0123456789ABCDEFFEDCBA9876543210

KSN 为:FFFF0000000000000000

得到的 IPEK 为:EFE8BA8E0216474AE09DE4DA59111A2E

第二步:计算 PIN Block ​

假设

PIN 为:123456

卡号为:4217123412341234

EVO Payment 使用的 PIN Block 格式为 ANSI X9.8(ISO Format 0),计算流程如下:

  1. 用卡号去掉最后一位,从倒数第二位向前取 12 位,得到:712341234123
  2. 在截取后的卡号前补 0,补足 16 位,得到:0000712341234123
  3. 用两位密码长度位后拼接密码,再后补 F,补足 16 位,得到:06123456FFFFFFFF
  4. 将 0000712341234123、06123456FFFFFFFF 异或得到 PIN Block:06124575BEDCBEDC

第三步:对 PIN Block 进行加密 ​

使用 IPEK 生成 PEK,然后对第二步中得到的 PIN Block 进行加密。

假设

IPEK 为:EFE8BA8E0216474AE09DE4DA59111A2E

PIN Block 为:06124575BEDCBEDC

KSN 为 FFFF0000000000000003

加密后得到密文为:3A13CFDF77DDB259

第四步:将密文放入请求报文中 ​

将报文中的 pinEncryptMethod 设置为您使用的签名算法,将 encryptedPin 设置为第三步中计算得到的签名值,将 keySerialNumber 设置为 PEK 对应的 KSN,最终得到最终要发送的报文:

json
{
  "pin": {
    "encryptedPin": "3A13CFDF77DDB259",
    "keySerialNumber": "FFFF0000000000000003",
    "pinEncryptMethod": "DUKPT"
  }
}

国密加密规则 ​

EVO Payment 支持使用 SM4 加密算法对 PIN 进行加密。

密钥使用规则 ​

在使用国密算法对 PIN 进行加密时,您需要先生成一个 ZMK 然后配置在 EVO Payment 系统中。然后调用 GET ZPK 接口获取用于加密 PIN 的 ZPK。

TIP

  1. 每次调用 GET ZPK 接口都会获取一个新的 ZPK,同时上一个 ZPK 还可以在 1 小时内继续使用。如果再次调用接口获取第三个 ZPK,此时第一个 ZPK 仍然保持 1 小时的有效期。
  2. 通过 GET ZPK 接口获取的 ZPK 是使用 SM4 算法用 ZMK 加密过的 hex 格式的密文,需要解密后使用。
  3. 加密过后的 ZPK 密文样例:f826a0355019c1fb828e57a7264ea254

密钥格式

**ZMK 明文格式:**32 个字符(0-9,A-F),不区分大小写,可机构提供两个分量或 CIL 提供两个分量,两个分量异或得到 ZMK 明文,加密全零得到 checkvalue,可核对是否一致

**ZPK 明文格式:**32 个字符(0-9,A-F),不区分大小写,hex 格式

第一步:计算 PIN Block ​

假设

PIN 为:123456

卡号为:4217123412341234

EVO Payment 使用的 PIN Block 格式为 ANSI X9.8(ISO Format 0),计算流程如下:

  1. 用卡号去掉最后一位,从倒数第二位向前取 12 位,得到:712341234123
  2. 在截取后的卡号前补 0,补足 32 位,得到:00000000000000000000712341234123
  3. 用两位密码长度位后拼接密码,再后补 F,补足 32 位,得到:06123456FFFFFFFFFFFFFFFFFFFFFFFF
  4. 将 00000000000000000000712341234123、06123456FFFFFFFFFFFFFFFFFFFFFFFF 异或得到 PIN Block:06123456FFFFFFFFFFFF8EDCBEDCBEDC

第二步:对 PIN Block 进行加密 ​

使用 SM4 算法对第一步中得到的 PIN Block 进行加密

  1. 加密算法:ECB
  2. 填充模式:pkcs#7
  3. 输出格式:Hex

假设

ZPK 明文为:0123456789abcdeffedcba9876543233

加密后得到密文为:3be3ae64b108d29c2a7475022d6d1a4d1e343a0b8e326f7235435a623f362199

第三步:将密文放入请求报文中 ​

将报文中的 pinEncryptMethod 设置为您使用的签名算法,将 encryptedPin 设置为第二步中计算得到的签名值,最终得到最终要发送的报文:

json
{
  "pin": {
    "encryptedPin": "3be3ae64b108d29c2a7475022d6d1a4d1e343a0b8e326f7235435a623f362199",
    "pinEncryptMethod": "SM4",
    "checkValue": "6hd43s"
  }
}

TIP

如果请求中的 checkValue 不存在,则会报错 B0079 Field: {xxx} value: {xxx} does not exist