DUKPT IPEK KSNPOS机的加密传输过程

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: DUKPT IPEK KSNPOS机的加密传输过程

DUKPT(Derived Unique Key Per Transaction)是被ANSI定义的一套密钥管理体系和算法,用于解决金融支付领域的信息安全传输中的密钥管理问题,应用于对称密钥加密MAC,PIN等数据安全方面。保证每一次交易流程使用唯一的密钥,采用一种不可逆的密钥转换算法,使得无法从当前交易数据信息破解上一次交易密钥。要求收单行与终端必须同步支持该项密钥管理技术。由交易发起端点(S-TRSM,如pos,ATM)与交易接收端点(R-TRSM,如收单行)两部分组成。注:TRSM(Tamper-Resistant Security Module)是一个具备阻止攻击能力的安全模块。TRSM具有抵御攻击能力。

以下内容引用自ANSI X9.24规范文档(Retail Financial Services Symmetric Key Management)

This standard establishes requirements and guidelines for the secure management and application-level

interoperability of keying operations. Such keys could be used for authenticating messages (see Reference 5), for

encrypting Personal Identification Numbers (PIN) (see Reference 4), for encrypting other data, and for encrypting

other keys.

DUKPT应用场景举例

Jacky到Wal-Mart购买了一双鞋,结帐时使用VISA信用卡刷卡,刷卡后POS需要与后台系统进行数据交互,将此交易的信息告知发卡行,交易信息的传递路径大概描述如下:

从信息传递的安全性上考虑:

  1. 上图的交易信息传递过程中,会涉及到一些敏感信息的传输,例如可能有卡片有效期、CVV2、密码等,如何保证这些信息的安全性?
  2. 每个结点如何校验接收到的数据是来自可信的相邻结点?即,如何校验数据的完整性,防止被恶意篡改?

于是,聪明的孩子就想到了使用DES/T-DES算法,针对敏感数据进行加密,解决了第一个问题;使用基于DES/T-DES的MAC算法,解决了报文校验问题。(为神马是T-DES和MAC?这不重要,我们要解释的是DUKPT!)

那么问题来了,既然使用了DES/T-DES这类的对称加密算法,就一定会涉及到对称密钥的交互问题。只有保证了密钥的安全性,对称加密才有意义。

于是,DUKPT应运而生。

DUKPT流程简析

说了半天,DUKPT到底干了些神马?别急,马上为你娓娓道来。

为了说明DUKPT流程,先介绍几个基本概念:

  • BDK(Base Derivation Key):DUKPT密钥体系的根密钥,一般是一个双倍长或三倍长的T-DES密钥。一定要保证它的安全性哦!
  • KSN(Key Serial Number):一串80bit的(20 hexadecimal digits)序号,由59bit的IKSN(Initial Key Serial Number)和21bit的EC(Encryption Counter)组成。所谓的“Unique Key Per Transaction”,全靠它啦!
  • PEK(PIN Encryption Key):顾名思义,加密PIN(卡片密码)的密钥咯!一般是双倍长的T-DES密钥。

依旧引用上图,我们单看POS和Acquirer Host这两个结点之间(其它结点之间的处理,基本类似):

  1. Acquirer在布放POS到Wal-Mart时,已经提前给这台POS的安全芯片中,灌输了BDK【BDK的灌输过程,是有Acquirer的安全部门保证的哦】,并:
  • 生成了EC=0的Initial PEK:Initial PEK = PEK_Derive(BDK, KSN with EC=0)
  • 销毁了终端中的BDK(保证BDK的安全性)
  1. 当然,BDK在Acquirer Host中肯的是有保存的(不然他收到交易后怎么解密!)。别担心,一般来说Acquirer Host都是使用硬件加密机(HSM/SafeNet)保存密钥的,基本不会存在密钥泄漏的风险。
  2. 重头戏来啦:Jacky在POS上进行刷卡交易,此时POS做了哪些事情呢?
    1、 Current KSN = IKSN and EC++【即,Current KSN中的EC = 1】
    2、 Current PEK = PEK_Derive(Initial PEK, Current KSN)
    3、 Encrypted PIN = T-DES(Opr=Encrypt, Current PEK, Clear PIN)
  3. 至此,Encrypted PIN已经得出来啦!POS开开心心的把Encrypted PIN放到交易报文里面,送给Acquirer Host咯。
  4. 等等!POS只送出一个Encrypted PIN,真的够了吗?
    想一下,Acquirer Host收到交易报文之后,需要解密Encrypted PIN的哦!怎么解密?Clear PIN = T-DES(Opr=Decrypt, Current PEK, Encrypted PIN)
    【淡定,这个步骤是在HSM里面做的,只有HSM/SafaNet知道clear PIN,Acquirer Host的软件是不知道的哦】
    问题又来了,Acquirer Host大叫:我怎么知道Current PEK(IPEK)是神马?我只知道BDK啊!
    Acquirer Host真是个笨蛋!人家POS都知道怎么算Current PEK,你咋不知道?同样的步骤算一下呗:
    1、 Initial PEK = PEK_Derive(BDK, KSN with EC=0)
    2、 Current PEK = PEK_Derive(Initial PEK, Current KSN)
    Acquirer Host再次大叫:我说了我只知道BDK啊!看看上面两个步骤的参数,我还需要Current KSN,才能算出Current PEK呢!
  5. 好吧,POS不得不承认自己的错误:不好意思刚刚只在交易报文里面塞进了Encrypted PIN,忘了把Current EC塞进去啦!
    于是,POS不得不屁颠屁颠的把Encrypted PIN和Current KSN都塞进交易报文,送给Acquirer Host
    于是,Acquirer Host收到报文后,开开心心的解密成功,可以进行后续交易处理啦。

于是,我们总结一下上述流程:

  1. 初始化:Acquirer Host和POS交互相同的BDK,且POS中销毁BDK,仅保存由BDK分散出来的Initial PEK
  2. 发生交易时,POS的处理:再重复一遍,不就是上面的这些步骤么
    1、 Current KSN = IKSN and EC++
    2、Current PEK = PEK_Derive(Initial PEK, Current KSN)
    3、Encrypted PIN = T-DES(Opr=Encrypt, Current PEK, Clear PIN)
    4、把Current KSN和Encrypted PIN放到交易报文里面,发送给Acquirer Host
  3. 收到交易时,Acquirer Host的处理:
    1、 Initial PEK = PEK_Derive(BDK, KSN with EC=0)
    2、Current PEK = PEK_Derive(Initial PEK, Current KSN)
    3、Clear PIN = T-DES(Opr=Decrypt, Current PEK, Encrypted PIN)
    4、后续交易处理

呼…说这么多,刚解释完DUKPT的第一轮计算方式… 想想如果是你来设计这个算法,接下来该怎么处理EC=2、EC=3…EC=n的情况呢?

我们回头看一下上文中提到的”发生交易时,POS的处理“:

1、 Current KSN = IKSN and EC++

2、Current PEK = PEK_Derive(Initial PEK, Current KSN)

3、Encrypted PIN = T-DES(Opr=Encrypt, Current PEK, Clear PIN)

4、把Current KSN和Encrypted PIN放到交易报文里面,发送给Acquirer Host

想一下,在这个追求用户体验的年代,刷卡交易的速度一定是评估刷卡体验的重要指标。

那么,为了提高速度,怎么简化一下上述流程呢?抛开算法层面的优化,很自然的一个想法:把能提起做的事情,先提前做起来!

哪些步骤可以提前做?看看上述流程中每个步骤的入参,好像只有Clear PIN是持卡人在交易发生时输入的,其它参数不都是POS内部的数据么!

这是个好消息!这样的话,我们可以在初始化POS(想想上文提到的“初始化”流程)时,就把EC=2、EC=3…EC=n时的每个EC对应的(Current Key)i 计算出来,提前保存到POS中,交易发生时,只需要EC++并取出相应的(Current Key)i ,就万事大吉啦!

呃,好像有哪里不对的样子……哦哦哦,EC=2、EC=3…EC=n,这个n到底是多少啊?要是有个几十上百万,POS中哪有那么大的空间给你存(Current Key)i呢!要知道,POS的硬件就那么一块小板子,每一个字节都是很宝贵的哦!

该死的,又是时间和空间互换的问题,那就找个平衡点咯!于是乎,ANSI果断的找到了这个平衡点:POS中预先存储的Current Key(插一句,这些Key都是后续交易中,EC++之后才用到的Key,是不是应该叫做Future Key啊?)数量,是21个!

【为啥是21?我咋知道!或许是这个数字比较吉利?不过想想EC的长度也是21个bit,好像发现了点儿神马哦…】

于是,POS中出现了21个寄存器,叫做Future Key Register,在POS初始化时,它们被依次填充了EC=1 … EC=21的Future Key

于是,我们更新一下POS初始化的流程:

1、 Acquirer给POS灌输BDK

2、Initial PEK = PEK_Derive(BDK, KSN with EC=0)

3、

(Future Key)1 = PEK_Derive(Initial PEK, KSN with EC=1) -> (Future Key Register)1

(Future Key)2 = PEK_Derive(Initial PEK, KSN with EC=2) -> (Future Key Register)2

……

(Future Key)21 = PEK_Derive(Initial PEK, KSN with EC=21) -> (Future Key Register)21

4、 为了保证密钥安全性,别忘了销毁BDK和Initial PEK!

ok啦,POS机曰:万事大吉,坐等刷卡!

那么,21个Future Key用完了咋办?当然后面接着生成啦。这里就有2个新问题了:

  1. 比较明显的问题:什么时机去生成和更新EC=22、EC=23…的Future Key?
    既然POS中只有21个寄存器,那当然得物尽其用啦!反正EC又不会重复使用(EC++操作是有上限的哦,后面会提到),EC=1的Future Key用过一次之后,就木有用啦!
    那就在POS的第一笔交易处理完成后,把(Future Key Register)1中保存的Key,更新成(Future Key)22吧!这样既不影响交易处理效率,又可以充分利用空间,多好啊!
  2. 比较隐晦的问题:(Future Key)22是怎么生成的呢?
    最直接的想法,跟(Future Key)1采用同样的方式呗:
    (Future Key)22 = PEK_Derive(Initial PEK, KSN with EC=22) -> (Future Key Register)1
    Stop!POS曰:我去哪儿找Initial PEK啊?之前初始化的第4步里面,已经把这玩意儿销毁了哎!
    呃,有点儿麻烦了,是之前不应该销毁Initial PEK吗?可是如果不销毁,后续所有的Key,都由Initial PEK分散得到的话,那这个Initial PEK可是个相当重要、相当机密的东东啦!
    嘿,换个思路如何?我现在是要生成(Future Key)22,而它要占用的地盘儿(寄存器),正是(Future Key Register)1,那我干脆就用(Future Key)1来分散得到(Future Key)22吧!
    于是: (Future Key)22 = PEK_Derive( (Future Key)1 , KSN with EC=22) -> (Future Key Register)1

ok,总算是把(Future Key)22搞定了,接下来就好说啦,以此类推呗:

(Future Key)23 = PEK_Derive( (Future Key)2 , KSN with EC=23) -> (Future Key Register)2

(Future Key)24 = PEK_Derive( (Future Key)3 , KSN with EC=24) -> (Future Key Register)3

……

(Future Key)42 = PEK_Derive( (Future Key)21 , KSN with EC=42) -> (Future Key Register)21

哦,又是21,好巧哦,又是一个轮回啊!接下来咋办?

(Future Key)43 = PEK_Derive( (Future Key)? , KSN with EC=43) -> (Future Key Register)?

好办啊!跟(Future Key)22一样处理呗:

(Future Key)43 = PEK_Derive( (Future Key)22 , KSN with EC=43) -> (Future Key Register)1

……

其实前文已经将DUKPT算法解释的差不多了,需要进一步说明的,就是Future Key的计算了。其实之前已经推理了一大堆了,我就直接把结果贴出来吧:

EC共有21个bit,每个bit可能的取值为“0”或“1”,那么如此多的EC,可以形成一棵树状结构:

说明一下,这棵树的组成是这样的:

  • 层次:树的每一层,EC中包含的bit为“1”的数量是固定的;即
  • 第0层的EC中,包含0个bit的“1”
  • 第1层的EC中,包含1个bit的“1”
  • 第2层的EC中,包含2个bit的“1”
  • 子结点:每个结点的子结点,均保留本结点的EC中所有为“1”的bit,并将最右侧的“1”后面的“0”,依次替换为“1”;例如
  • EC=(1000)2的结点,有(1100)2、(1010)2和(1001)2这3个子节点
  • EC=(1100)2的结点,有(1110)2和(1101)2这2个子结点
  • 深度:为保证算法效率,DUKPT规定,上面那棵树的最大深度为10,即
  • 有效的EC中,包含“1”的bit个数 <= 10
  • 计算过程中遇到无效的EC,直接跳过
  • 这样的话,有效的EC个数为100多万个
  • Future Key:与EC是对应的
  • 每个EC,对应一个Future Key
  • 子结点EC的Future Key,是被父结点EC的Future Key加密的
  • 即,上面的那棵树,就是一棵Future Key计算体系的树

好啦,DUKPT基本上就是这样了

哦对了,再补充一句: 上述流程只讲解到了Future Key,但实际用于数据(如PIN、MAC等)加密的,其实不是直接拿Future Key来用的,而是Future Key xor 分散向量得到的工作密钥

  • PIN密钥的分散向量:00000000000000FF00000000000000FF
  • MAC密钥的分散向量:000000000000FF00000000000000FF00
    【其它的分散向量好像还有,但没有在ANSI x9.24规范(2004版)中提及】

话说看到评论才发现,全文对于PEK_DERIVE的步骤,没有进行明确说明, 不多说,直接上图吧

简要说明:

  1. 黄色底色的2个框框,是PEK_DERIVE的2个入参;绿色底色的框框,是PEK_DERIVE的结果
  2. 图中的“Set Bit”(右边KSN的黄色框框 下面的步骤),是一个很简单的步骤:
  • 取KSN中最右边的21bit的EC(例如,01100000…1000,共21bit)
  • 得到EC中最右侧的bit “1”(01100000…1 000)
  • 将EC其余bit置为0,即获得Set Bit的结果(00000000…1 000)

转自 https://blog.csdn.net/chy555chy/article/details/51878096


相关文章
|
7月前
|
Linux 网络安全 数据安全/隐私保护
Linux vsFTPd服务详解——文件加密传输配置
Linux vsFTPd服务详解——文件加密传输配置
244 2
|
25天前
|
存储 安全 数据安全/隐私保护
Codota的数据加密技术包括静态数据加密和传输中的数据加密
Codota的数据加密技术包括静态数据加密和传输中的数据加密
46 4
|
4月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
4月前
|
网络协议 安全 网络安全
DNS服务器加密传输
【8月更文挑战第18天】
371 15
|
4月前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
415 0
|
5月前
|
安全 算法 Java
Java中的数据加密与安全传输
Java中的数据加密与安全传输
|
6月前
|
存储 安全 算法
RSA非对称加密算法中的密钥对生成与传输
RSA非对称加密算法的密钥对生成与传输是信息安全领域的核心问题之一。密钥生成过程需要保证随机性和安全性,而密钥的传输则需要选择适当的方式来确保其保密性和完整性。通过合理的密钥管理和保护措施,可以有效地利用RSA算法保护通信安全,防止信息泄露和篡改。在实际应用中,用户和系统管理员需要结合具体情况选择最佳的密钥生成和传输策略,以达到最佳的安全性和效率。
|
7月前
|
安全 网络协议 应用服务中间件
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
|
6月前
|
网络安全 数据安全/隐私保护
邮件Demo(SSL加密传输)
private final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; private String smtpServer; // SMTP服务器地址 private String port; // 端口 private String username; // 登录SMTP服务器的用户名 private String password; // 登录SMTP服务器的密码 private List<String> recipients = new ArrayList<String>(); // 收件人地址集合
44 0
|
7月前
|
前端开发 算法 JavaScript
实现注册登录时数据的加密传输(含前后端具体代码)
实现注册登录时数据的加密传输(含前后端具体代码)