首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GlobalPlatform UICC SCP03 AES卡挑战赛

GlobalPlatform UICC SCP03 AES卡挑战赛
EN

Stack Overflow用户
提问于 2013-08-13 23:09:55
回答 2查看 3.3K关注 0票数 1

我正在GlobalPlatform UICC (2.2.1)卡的测试工具中实现SCP03。该工具的代码是用C#编写的,我正在尝试使用dotNet AES类。

我遇到的问题是我的代码不能重现卡片发送的卡片挑战。我不确定这是因为我提供给AES加密器的数据,还是我没有正确使用AES加密器。

我的代码基于GP Spec 2.2修正案-D,它有点模糊,至少在生成卡片挑战的过程中是这样的,并且没有指定初始向量。

我创建的派生数据如下:-

代码语言:javascript
复制
00 00 00 00 00 00 00 00 00 00 00 - 11 bytes all zero

02 - card challenge identifier

00 - separator

00 40 - length

01 - counter

00 00 02 - key sequence counter (received from the card)

A0 00 00 01 51 00 00 00 - appID of the currently selected application (the ISD)

80 00 00 00 00 - padding to 32 bytes.

初始向量(IV) i已设置为16个字节的零。

为了创建卡片质询,我使用静态密钥K-ENC,它的值为:

代码语言:javascript
复制
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

卡片返回的卡片质询(验证无误)为:-

代码语言:javascript
复制
83 FA 04 2C 5C 10 F7 78

我写的重现卡片挑战的代码是:

代码语言:javascript
复制
public static Byte []
GenerateCardChallengeScp03
    (   UInt32      seqCounter,
        Byte []     selectedAid,
        Byte []     baseKeyEnc)
{
    Byte []     finalDerivationData = null;
    Byte []     sequenceCounter     = new Byte [3];
    Byte []     derivationData      = new Byte [16];

    for (int i = 0; i < derivationData.Length; i++)
        derivationData [i] = 0x00; 

    sequenceCounter [0] = (Byte) (seqCounter / 0X10000);
    sequenceCounter [1] = (Byte) (seqCounter / 0X100);
    sequenceCounter [2] = (Byte) (seqCounter);

    derivationData [11] = 0x02; // Card challenge
    derivationData [12] = 0x00; // Separator
    derivationData [13] = 0x00; // MSB length
    derivationData [14] = 0x40; // LSB length
    derivationData [15] = 0x01; // Counter

    finalDerivationData = GP_Utils.ConcatenateArrays (derivationData, sequenceCounter);
    finalDerivationData = GP_Utils.ConcatenateArrays (finalDerivationData, selectedAid);

    Byte []                     icv         = new Byte [] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    Byte []                     inputData   = PadForAesEncryption_0x80 (finalDerivationData);
    AesCryptoServiceProvider    aes         = new AesCryptoServiceProvider ();

    aes.BlockSize       = 128;
    aes.FeedbackSize    = 128;
    aes.KeySize         = baseKeyEnc.Length * 8;
    aes.Mode            = CipherMode.CBC;
    aes.Key             = baseKeyEnc;
    aes.IV              = icv;
    aes.Padding         = PaddingMode.None;

    ICryptoTransform    encryptor   = aes.CreateEncryptor ();
    Byte []             outputData  = encryptor.TransformFinalBlock (inputData, 0, inputData.Length);
    Byte []             cardChallenge = new Byte [8];

    for (int i = 0; i < cardChallenge.Length; i++)
        cardChallenge [i] = outputData [i]; 

    return (cardChallenge);
}

那么,我没有做什么,或者做错了什么呢?

EN

回答 2

Stack Overflow用户

发布于 2013-11-15 05:28:23

不确定你是否找到了答案。如果我没记错的话,你应该按照NIST 800-38B计算CMAC来计算卡片挑战,而不仅仅是普通的AES加密。

票数 1
EN

Stack Overflow用户

发布于 2014-02-25 21:46:19

我可以验证你的卡片挑战。请看一下crypto.c。有一个使用calculate_CMAC_aes的名为calculate_card_challenge_SCP03的函数。它是C代码,但您应该能够将其转换为C#代码。我使用的是来自OpenSSL的加密函数,所以C#应该也有类似的东西。

代码语言:javascript
复制
 static void test_card_challenge_SCP03()
 {
    BYTE sequenceCounter[3] = {0x00, 0x00, 0x02};
    BYTE invokingAID[8] = {0xA0, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00};
    BYTE calculatedCardChallenge[8];
    BYTE cardChallenge[8] = {0x83,0xFA,0x04,0x2C,0x5C,0x10,0xF7,0x78};
    OPGP_ERROR_STATUS status;

    status = calculate_card_challenge_SCP03((PBYTE)OPGP_VISA_DEFAULT_KEY, (PBYTE)sequenceCounter, invokingAID, sizeof(invokingAID), calculatedCardChallenge);
    sput_fail_unless(OPGP_ERROR_CHECK(status) == 0, NULL);
    OPGP_LOG_HEX(_T("Calculated card challenge: "), calculatedCardChallenge, 8);
    OPGP_LOG_HEX(_T("Given card challenge: "), cardChallenge, 8);
    sput_fail_unless(memcmp(calculatedCardChallenge, cardChallenge, 8) == 0, "Card Challenge Comparison");
 }

您使用什么卡进行测试?我正在寻找一种公开可用的测试卡,带有实现SCP03的已知密钥的SCP03支持。我使用的是来自Gemalto商店的Gemalto IDPrime PIVCard2.0卡,但这似乎使用了一些秘密的、未记录的密钥、未记录的密钥派生或与标准不兼容。

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

https://stackoverflow.com/questions/18212788

复制
相关文章

相似问题

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