DUKPT流程简析

一、DUKPT流程简析

接着上一篇文章DUKPT
在这里插入图片描述
依旧引用上图,我们单看POS和Acquirer Host这两个结点之间(其它结点之间的处理,基本类似):

Acquirer在布放POS到商场时,已经提前给这台POS的安全芯片中,灌输了BDK,并:生成了EC=0的Initial PEK:Initial PEK =PEK_Derive(BDK, KSN with EC=0),然后销毁了终端中的BDK(保证BDK的安全性)。当然,BDK在Acquirer Host中肯的是有保存的。一般来说Acquirer Host都是使用硬件加密机(HSM/SafeNet)保存密钥的,基本不会存在密钥泄漏的风险。

重头戏来啦:小明在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)

至此,Encrypted PIN已经得出来啦!POS开开心心的把Encrypted PIN放到交易报文里面,送给Acquirer Host咯。

等等!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呢!

好吧,POS不得不承认自己的错误:不好意思刚刚只在交易报文里面塞进了Encrypted PIN,忘了把Current EC塞进去啦!

于是,POS不得不屁颠屁颠的把Encrypted PIN和Current KSN都塞进交易报文,送给Acquirer Host
于是,Acquirer Host收到报文后,开开心心的解密成功,可以进行后续交易处理啦。

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

初始化:Acquirer Host和POS交互相同的BDK,且POS中销毁BDK,仅保存由BDK分散出来的Initial PEK
发生交易时,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
收到交易时,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个新问题了:

比较明显的问题:什么时机去生成和更新EC=22、EC=23…的Future Key?

既然POS中只有21个寄存器,那当然得物尽其用啦!反正EC又不会重复使用(EC++操作是有上限的哦,后面会提到),EC=1的Future Key用过一次之后,就木有用啦!

那就在POS的第一笔交易处理完成后,把(Future Key Register)1中保存的Key,更新成(Future Key)22吧!这样既不影响交易处理效率,又可以充分利用空间,多好啊!

比较隐晦的问题:(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的步骤,没有进行明确说明, 不多说,直接上图吧
在这里插入图片描述
简要说明:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸福在路上wellbeing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值