技术文章
MAC 命令剖析
ID TECH 的许多客户都对 点对点加密(P2PE)颇感兴趣;为满足 PCI 严格的 P2PE 合规要求,客户通常会考虑采用 SRED(数据安全读取与交换)支付设备。此类设备不仅能在数据采集点对数据进行加密(ID TECH 的所有设备都具备此能力),还集成了防篡改检测、篡改时自动数据清零以及其他专用安全功能。
在这些"其他专用安全功能"中,最重要的便是命令的 MAC 认证。
在密码学中,消息认证码(MAC)是一段简短的代码,用于让消息接收方对消息进行认证——换言之,确认消息确实来自可信的发送方。MAC 值通过将消息与发送方和接收方共享的密钥相结合,既保护消息的数据完整性,也保护其真实性。消息以明文形式发送,同时还会发送"消息加 MAC"(其中包含已加密的密钥)。任何持有该密钥的人都能判断消息(及其附带的 MAC 内容)是否来自掌握同一密钥的另一方。
在 ID TECH 基于 SRED 的读卡器中,某些敏感命令受到 MAC 保护,这意味着设备只有在命令附带可被验证的 MAC 哈希值(使用设备中已存储的密钥)时才会执行该命令。命令发送方在生成 MAC 哈希时,必须使用与设备验证时相同的密钥。
举个例子可能会更清楚。
假设您要在 ID TECH Augusta S 读卡器(一款 SRED 设备)上设置日期和时间。"设置日期和时间"命令被视为敏感命令,因为不应允许未经授权的一方对交易进行回溯日期(或以其他方式更改)。(其他"敏感"命令例如包括:向白名单添加或从中移除卡片的命令,或修改设备证书撤销列表的命令。)
通常情况下,设置非 SRED Augusta 的日期和时间使用固件命令 78 53 01 50,后跟载荷长度(0x08),然后是日期/时间长度(0x06),接着是 6 字节的日期和时间(格式为 YY MM DD HH MM SS),最后是"MAC 长度"——对于非 SRED 设备,该值为零。在 Augusta S 中,上述格式相同,但载荷长度为 0x26,"MAC 长度"为 0x1E,因为末尾会额外附加 30 字节的"MAC 载荷"。
当然,在 Augusta 中,整条命令需要按照 ID TECH 的 NGA 协议进行格式化,即在命令结构前加上 STX(0x02)和两个小端序的长度字节,在命令结构末尾加上 LRC、校验和以及 ETX(0x03)。整条命令最终的 MAC 版本如下所示(命令字节以黄色标注):
02 2B 00 78 53 01 50 26 06 17 11 10 09 15 00 1E 10 00 4E C7 DF CF 04 D3 3C C6 EC 6F 50 92 00 86 A1 DD 0A 00 62 99 49 00 00 00 00 00 00 02 EB F9 03
让我们逐段进行解析:
02 为 STX。
2B 00 为整个结构的(小端序)长度,不包括 LRC/校验和/ETX 尾部。
78 53 01 50 为"设置日期和时间"固件命令。
26 (十六进制)表示后接 38 字节的载荷。
06 表示日期/时间由 6 字节组成,即:
17 11 10 09 15 00 ——2017 年 11 月 10 日,上午 09:15:00。
1E 表示后接 30 字节的 MAC 载荷。
10 00 为小端序的长度值 16(因为所有 ID TECH 的 MAC 哈希都是 16 字节长)。
4E C7 DF CF 04 D3 3C C6 EC 6F 50 92 00 86 A1 DD 为 16 字节的 MAC 哈希值,即"HMAC"。
0A 00 为小端序的长度值 10,用于后续的 KSN。
62 99 49 00 00 00 00 00 00 02 为 MAC KSN。
EB 为纵向冗余校验值。
F9 为从 78 到最后一个 KSN 字节(02)之间所有内容的 8 位校验和。
03 为 ETX(传输结束)。
构造这条命令并没有什么特别困难之处。难以一目了然的部分是 KSN 和 HMAC(哈希值本身)。
MAC KSN
MAC KSN(密钥序列号)需要在需要时向设备查询获取。如果您熟悉 ANSI X9.24-1(每次交易派生唯一密钥标准)您应该知道,KSN 是一个 10 字节的值,其中低 21 位构成一个计数器,每次使用后都会递增。您可能没有意识到的是,如果设备包含多个 DUKPT 密钥(例如 Data、MAC 和 PIN 密钥),每个密钥都有自己专属的 KSN,且它们之间的递增并不同步。不过 KSN 是一个公开值,您可以随时通过完整格式化的命令 02090078463e040005010000000603 查询 ID TECH 的 Augusta 中的 MAC KSN。
KSN 之所以重要,是因为它参与了 MAC 密钥的计算,而该密钥每次使用都是唯一的(因此可防止重放攻击)。关于 KSN 和 DUKPT 密钥派生的更多信息,请参阅 我之前关于该主题的两篇系列文章.
HMAC 派生
接下来进入技术细节部分。
HMAC(参见 RFC 2104)是行业公认的创建 MAC 哈希的方法,使用:
- — 一个 128 位的一次性密钥
- — 任意的消息载荷
- — SHA-256 哈希算法
所述密钥按照标准 DUKPT 规则,使用 MAC KSN 和设备的 IPEK(IPEK 又派生自 BDK)动态派生而来。该规则规定了一种专门派生 MAC 密钥的方式(区别于数据密钥或 PIN 密钥)。详细说明请参阅 我之前的两篇系列文章
这个看起来令人生畏的 HMAC 哈希值按以下公式计算:
H( (K' ⊕ opad) ‖ H( (K' ⊕ ipad) ‖ m) )
别被它吓到。其实理解起来很简单。值 K 是 128 位密钥。 K' (k-prime)表示同一密钥,用零填充至总长度 64 字节。
该 ipad (内填充)只是常量 36363636…,重复至长度 64 字节。
K' ⊕ ipad 表示将零填充后的密钥与 ipad 值按位异或(XOR)组合,这是一种深受计算机科学爱好者喜爱的按位算术运算。
K' ⊕ ipad) ‖ m 表示将消息 (m) 附加到上面得到的值之后。只需把字节拼接到末尾即可。(此时长度会超过 64 字节,不必担心。)
H( (K' ⊕ ipad) ‖ m) 表示对括号中的整个值应用您的哈希函数(这里是 SHA-256)。
完成该步骤后,您需要将结果附加到 K' ⊕ opad之后,其中 opad(外填充)是由常量 5C5C5C5C… 重复至 64 字节长度构成。然后再对整体进行一次哈希运算。
顺便说一下,ipad 和 opad 的值是由该算法的原作者任意选定的,但选择方式旨在最大化哈希前半部分和后半部分之间的汉明距离(即位差异)。哈希分两部分嵌套进行,以防止各种形式的伪造。
为了方便您生成 HMAC 值,ID TECH 在线提供了一个 HTML 表单 此处,您可以在其中输入 KSN 和 BDK(根密钥)值,派生您的 MAC 密钥,并使用 HMAC(通过 SHA-256)创建 32 字节的 MAC 哈希值。请务必尝试 "Generate HMAC (with verbose output)" (生成 HMAC 并显示详细输出)选项,该选项位于表单顶部的下拉菜单中。您将获得一份非常实用的详细输出跟踪记录,清晰地解释 HMAC 各组成部分的具体内容。
如果您使用我们的在线工具,以 KSN 值 62 99 49 00 00 00 00 00 00 02 和根密钥(BDK)值 0123456789ABCDEFFEDCBA9876543210(即 ANSI 标准测试密钥)生成 MAC 密钥,您得到的 MAC 密钥应为 3E4A480ACE8B239B9539E6053EAB03D9。如果使用该密钥对载荷 78 53 01 50 26 06 17 11 10 09 15 00 1E 10 00 应用 HMAC 算法,您应得到一个 32 字节的 HMAC 哈希值,其前 16 字节为 4EC7DFCF04D33CC6EC6F50920086A1DD。(ID TECH 只使用前 16 字节。)这就是将添加到"Set Date and Time"命令中的神奇"指纹"。读卡器会查看明文载荷字节,并使用自身的 KSN 和内部密钥派生代码,生成与您命令中包含的相同的 HMAC 值,从而验证该命令必然来自知晓神奇 BDK (0123456789ABCDEFFEDCBA9876543210) 的来源,即可信来源。
对 DUKPT、HMAC、SRED 或 P2PE 有疑问?请联系我们的专家。我们随时为您提供帮助:
