首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解密DUKPT加密的轨道数据

解密DUKPT加密的轨道数据
EN

Stack Overflow用户
提问于 2012-08-01 06:36:34
回答 2查看 11.6K关注 0票数 13

正如标题所说,我正在尝试解密来自支持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/

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-04 07:17:43

我花了太多的时间研究可怕的X9.24规范,最终通过我的供应商的例子实现了加密和解密,营销部门立即决定更换供应商。因为它是一个标准,你会认为任何人的实现都是一样的。我希望如此。无论如何,在实现方式上有很多不同之处。你必须研究细节,以确保你的工作与你的另一方是一样的。

但这不是你的问题。

首先,如果您需要解密来自信用卡的数据轨道,您可能对生成一个密钥感兴趣,该密钥将基于原始的超级秘密Base派生密钥来解密数据。这与MAC生成没有任何关系,只是在那个可怕的规范中提到的。如果在来自HSM的完整密钥序列号的计数器部分中设置了位,则需要为该密钥序列号和设备ID生成IPEK,并重复应用规范中的“不可逆密钥生成过程”。

我的代码的这一部分看起来像这样:(很抱歉在一篇文章中列出了这么长的清单。)

代码语言:javascript
复制
/*
 * 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模式)。我的代码看起来像这样:

代码语言:javascript
复制
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

票数 36
EN

Stack Overflow用户

发布于 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中的相关代码

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11750036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档