13

正如标题所说,我正在尝试解密来自启用 DUKPT 的扫描仪的 DUKPT 加密轨道数据。

我有 DUKPT 的 ANSI 标准 (X9.24),并成功实现了从 KSN 和 BDK 生成 IPEK 的能力。此外,我已经成功实现了通过对 PIN 加密密钥进行异或来生成左右 MAC 请求和响应密钥的能力。最后,我能够生成 EPB。

从这里开始,我不明白如何从我生成的 L/R 密钥生成 MAC 请求和响应。

最后,一旦我到达那一步,接下来会发生什么?我什么时候才能真正拥有解密启用 DUKPT 的设备发送的轨道数据的密钥?

我知道泰雷兹模拟器和 jPOS。我的代码目前正在引用 Thales Simulator 来完成所有工作。但是,文件解密过程只是没有返回预期的数据。

如果有人可以提供一些有关解密轨道数据的见解,将不胜感激。

http://thalessim.codeplex.com/

http://jpos.org/

4

2 回答 2

36

我花了太多时间研究可怕的 X9.24 规范,最终让加密和解密都与我的供应商的示例一起工作,营销部门迅速决定更换供应商。因为它是一个标准,你会认为任何人的实现都是一样的。我希望。无论如何,事物的实现方式存在差异。您必须研究细则,以确保您的工作方式与另一方相同。

但这不是你的问题。

首先,如果您需要从信用卡中解密数据轨道,您可能有兴趣生成一个密钥,该密钥将根据原始超级机密 Base Derivation Key 解密数据。这与 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 的 80 位密钥序列号 crypt 是一个 64 位数据块,因为我使用的是 openSSL,所以我拥有 DES_cblock 类型的数据。key 是一个 128 位双 DES_cblock 结构。keyGen 例程几乎是从规范第 50 页的“不可逆密钥生成过程”本地子例程中逐字记录的。

最后,密钥变量将包含几乎可以用于解密的密钥。编写规范的家伙在关键点上添加了一些“变体”行为,让我们保持警觉。如果密钥要用于解密数据流(例如信用卡轨道),则需要将字节 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 规范有一些不足之处,但技术没问题。

祝你好运。/鲍勃·布莱恩

于 2012-08-03T23:17:42.823 回答
3

对于数据加密,变体是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

于 2013-04-23T21:28:13.460 回答