正如标题所说,我正在尝试解密来自支持DUKPT的扫描仪的DUKPT加密轨道数据。
我有用于DUKPT的ANSI标准(X9.24),并且已经成功地实现了从KSN和BDK生成IPEK的能力。此外,我已经成功地实现了通过XORing个人识别码加密密钥生成左和右MAC请求和响应密钥的能力。最后,我能够生成EPB。
从这里开始,我不知道如何从我生成的L/R密钥生成MAC请求和响应。
最后,一旦我完成了这一步,接下来会发生什么呢?什么时候我才能真正拥有用于解密由支持DUKPT的设备发送的轨道数据的密钥?
我知道泰利斯模拟器和jPOS。我的代码目前正在引用Thales Simulator来完成所有的工作。但是,文件解密过程并没有返回预期的数据。
如果任何人能提供一些关于解密轨道数据的见解,将不胜感激。
http://thalessim.codeplex.com/
http://jpos.org/
发布于 2012-08-04 07:17:43
我花了太多的时间研究可怕的X9.24规范,最终通过我的供应商的例子实现了加密和解密,营销部门立即决定更换供应商。因为它是一个标准,你会认为任何人的实现都是一样的。我希望如此。无论如何,在实现方式上有很多不同之处。你必须研究细节,以确保你的工作与你的另一方是一样的。
但这不是你的问题。
首先,如果您需要解密来自信用卡的数据轨道,您可能对生成一个密钥感兴趣,该密钥将基于原始的超级秘密Base派生密钥来解密数据。这与MAC生成没有任何关系,只是在那个可怕的规范中提到的。如果在来自HSM的完整密钥序列号的计数器部分中设置了位,则需要为该密钥序列号和设备ID生成IPEK,并重复应用规范中的“不可逆密钥生成过程”。
我的代码的这一部分看起来像这样:(很抱歉在一篇文章中列出了这么长的清单。)
/*
* Bit "zero" set (this is a 21 bit register)(ANSI counts from the left)
* This will be used to test each bit of the encryption counter
* to decide when to find another key.
*/
testBit=0x00100000;
/*
* We have to "encrypt" the IPEK repeatedly to find the current key
* (See Section A.3). Each time we encrypt (generate a new key),
* we need to use the all prior bits to the left of the current bit.
* The Spec says we will have a maximum of ten bits set at any time
* so we should not have to generate more than ten keys to find the
* current encryption key.
*/
cumBits=0;
/*
* For each of the 21 possible key bits,
* if it is set, we need to OR that bit into the cumulative bit
* variable and set that as the KSN count and "encrypt" again.
* The encryption we are using the goofy ANSI Key Generation
* subroutine from page 50.
*/
for(int ii=0; ii<21; ii++)
{
if( (keyNumber&testBit) != 0)
{
char ksr[10];
char eightByte[8]={0};
cumBits |= testBit;
ksn.count=cumBits; /* all bits processed to date */
memcpy(ksr, &ksn,10); /* copy bit structure to char array*/
memcpy(crypt,&ksr[2],8); /* copy bytes 2 through 9 */
/*
* Generate the new Key overwriting the old.
* This will apply the "Non-reversible Key Generation Process"
* to the lower 64 bits of the KSN.
*/
keyGen(&key, &crypt, &key);
}
testBit>>=1;
}其中keyNumber是来自ksn的当前计数器ksn是一个80位结构,其中包含来自HSM crypt的80位密钥序列号是一个64位数据块我有它的类型DES_cblock,因为我使用的是openSSL。key是128位双DES_cblock结构。keyGen例程几乎与规范第50页上的“不可逆键生成过程”本地子例程完全相同。
最后,key变量将包含几乎可用于解密的密钥。写规范的家伙给钥匙添加了一些“不同”的行为,以保持我们的警觉。如果密钥用于解密诸如信用卡轨道之类的数据流,则需要将字节5和13与0xFF进行异或运算,并且三重DES将密钥本身加密(ECB模式)。我的代码看起来像这样:
DOUBLE_KEY keyCopy;
char *p;
p=(char*)&key;
p[ 5]^=0xff;
p[13]^=0xff;
keyCopy=key;
des3(&keyCopy, (DES_cblock *)&key.left, &key.left);
des3(&keyCopy, (DES_cblock *)&key.right, &key.right);如果您使用它来解密PIN块,则需要将字节7和15与0xFF进行异或运算。(我不能100%确定这是否也适用于流模式,但我的供应商将其省略了。)
如果是PIN块,将在ECB模式下使用3-DES进行加密。如果是数据流,将在CBC模式下使用零初始向量进行加密。
(我有没有提到过我不太喜欢这个规范?)有趣的是,如果服务器端(上面)记住并拒绝先前使用的密钥,则可以在非硬件的防篡改安全模块中使用加密端。这项技术相当整洁。虽然ANSI规范还不够完善,但它的技术还是不错的。
祝好运。/Bob Bryan
发布于 2013-04-24 05:28:13
对于数据加密,变体是0000000000FF0000.0000000000FF0000,因此您需要对字节5和13进行异或,而不是7和15。此外,您还需要对每个关键部分(左侧和右侧)执行额外的3DES自加密步骤。
以下是jPOS https://github.com/jpos/jPOS/blob/master/jpos/src/main/java/org/jpos/security/jceadapter/JCESecurityModule.java#L1843-1856中的相关代码
https://stackoverflow.com/questions/11750036
复制相似问题