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);
}
それで、私がしていないこと、または間違っていることは何ですか?