【问题标题】:Decrypting DUKPT Encrypted Track Data解密 DUKPT 加密的轨道数据
【发布时间】:2012-07-29 19:19:51
【问题描述】:

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

【问题讨论】:

    标签: ansi encryption jpos credit-card-track-data


    【解决方案1】:

    我花了太多时间研究可怕的 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 页的“不可逆密钥生成过程”本地子例程中逐字记录的。

    最后,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 规范有一些不足之处,但技术还可以。

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

    【讨论】:

    • 这是一些很棒的信息。感谢您抽出宝贵时间做出如此详细的回应。我一定会继续你提供的工作。
    • 我希望我能给你一千张赞成票。互联网上最好的资源。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2014-03-03
      • 2012-01-23
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 2013-09-18
      • 2016-09-13
      相关资源
      最近更新 更多