1

GlobalPlatform UICC (2.2.1) カードのテスト ツールに SCP03 を実装しています。ツールのコードは C# で記述されており、dotNet AES クラスを使用しようとしています。

私が抱えている問題は、コードがカードから送信されたカード チャレンジを再現できないことです。これが AES エンクリプターに提供しているデータによるものなのか、それとも AES エンクリプターを正しく使用していないためなのかはわかりません。

私はコードを GP Spec 2.2 Amendment-D に基づいていますが、これは少なくともカード チャレンジを生成する過程では少しあいまいで、初期ベクトルを指定していません。

私が作成する派生データは次のとおりです。

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) を 16 バイトのゼロに設定しました。

カード チャレンジの作成には、次の値を持つ静的キー K-ENC を使用しています。

40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

カードによって返されるカード チャレンジ (正しいことが確認された) は次のとおりです。

83 FA 04 2C 5C 10 F7 78

カードチャレンジを再現するために私が書いたコードは次のとおりです。

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);
}

それで、私がしていないこと、または間違っていることは何ですか?

4

2 に答える 2