I sent 80 50 00 00 08 00 00 00 00 00 00 00 00
[INITILIZE UPDATE Command] via opensc-tool to my java card and received 00 00 11 60 01 00 8A 79 0A F9 FF 02 00 11 79 11 36 5D 71 00 A5 A5 EC 63 BB DC 05 CC
[Init Response] as its response from the card.
As you see:
In the command,I send 00 00 00 00 00 00 00 00
as Host Challenge, And in the response :
00 00 11 60 01 00 8A 79 0A F9
= Key diversification data
FF 02
= Key information
00 11 79 11 36 5D 71 00
= Card challenge
A5 A5 EC 63 BB DC 05 CC
= Card cryptogram
Now I want to check myself,if the card cryptogram is OK or not. How I can do it? for example I encrypt 00 00 00 00 00 00 00 00
in this site under a 3DES cryptography algorithm [with keys of my card = 4041...4F
], but the output is not equal with card cryptogram that I wrote above. Why?
And the next question is, if I want to send EXTERNAL AUTHENTICATION command to the card, what is its data field (after the above INITILIZE UPDATE)?
Update:
This is GPJ output :
C:\Users\ghasemi\Desktop\gpj-20120310>GPJ
C:\Users\ghasemi\Desktop\gpj-20120310>java -jar gpj.jar
Found terminals: [PC/SC terminal ACS CCID USB Reader 0]
Found card in terminal: ACS CCID USB Reader 0
ATR: 3B 68 00 00 00 73 C8 40 12 00 90 00
.
.
.
DEBUG: Command APDU: 00 A4 04 00 08 A0 00 00 00 03 00 00 00
DEBUG: Response APDU: 6F 10 84 08 A0 00 00 00 03 00 00 00 A5 04 9F 65 01 FF 90 00
Successfully selected Security Domain OP201a A0 00 00 00 03 00 00 00
DEBUG: Command APDU: 80 50 00 00 08 7F 41 A9 E7 19 37 83 FA
DEBUG: Response APDU: 00 00 11 60 01 00 8A 79 0A F9 FF 02 00 1B 9B 95 B9 5E 5E BC BA 51 34 84 D9 C1 B9 6E 90 00
DEBUG: Command APDU: 84 82 00 00 10 13 3B 4E C5 2C 9E D8 24 50 71 83 3A 78 AE 75 23
DEBUG: Response APDU: 90 00
DEBUG: Command APDU: 84 82 00 00 08 13 3B 4E C5 2C 9E D8 24
DEBUG: Response APDU: 90 00
C:\Users\ghasemi\Desktop\gpj-20120310>
So :
Host_Challenge :: 7F41A9E7193783FA
Diversification_Data :: 0000116001008A790AF9
Key_Information :: FF02
Sequence_Counter :: 001B
Card_Challenge :: 9B95B95E5EBC
Card_Cryptogram :: BA513484D9C1B96E
Host_Cryptogram[16,24] = 13 3B 4E C5 2C 9E D8 24
Now,lets make our Host_Cryptogram Manually :
Derivation_data=derivation_const_ENC|sequence_counter|0000 0000 0000 0000 0000 0000
Derivation_Data = 0182001B000000000000000000000000
k_ENC :: 404142434445464748494A4B4C4D4E4F
IV = 00 00 00 00 00 00 00 00
S_ENC = encrypt(TDES_CBC, K_ENC, IV, derivation_data)
So :
I used http://tripledes.online-domain-tools.com/ and its output for above values was :
S_ENC = 448b0a5967ca246d058703ff0c694f15
And :
Padding_DES = 80 00 00 00 00 00 00 00
Host_auth_data = sequence_counter | card_challenge | host_challenge | padding_DES
IV = Card_Cryptogram :: BA513484D9C1B96E
host_cryptogram = encrypt(TDES_CBC, S_ENC, IV, host_auth_data)
So :
Host_Authentication_Data : 001B9B95B95E5EBC7F41A9E7193783FA8000000000000000
Again, I used http://tripledes.online-domain-tools.com/
and :
Host_Cryptogram : 3587b531db71ac52392493c08cff189ce7b9061029c63b62
So :
Host_Cryptogram[16,24] = e7b9061029c63b62
Why these two way [manually and GPJ output] give us two host cryptogram?
From the INITIALIZE UPDATE command you send, you get
host_challenge = 00 00 00 00 00 00 00 00
In response to the INITIALIZE UPDATE command, you get
diversification_data = 00 00 11 60 01 00 8A 79 0A F9
key_information = FF 02
sequence_counter = 00 11
card_challenge = 79 11 36 5D 71 00
card_cryptogram = A5 A5 EC 63 BB DC 05 CC
The key information indicates SCP02 (02
). The key diversification data may be used to derive the card-specific K_ENC. Lets assume we have a K_ENC like this
K_ENC = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
We can then derive the session encryption key like this
derivation_const_ENC = 01 82
derivation_data = derivation_const_ENC | sequence_counter | 00 00 00 00 00 00 00 00 00 00 00 00
IV = 00 00 00 00 00 00 00 00
S_ENC = encrypt(TDES_CBC, K_ENC, IV, derivation_data)
Next, we can assemble the authentication data used to calculate the host cryptogram:
padding_DES = 80 00 00 00 00 00 00 00
host_auth_data = sequence_counter | card_challenge | host_challenge | padding_DES
Then we can use the session encryption key to encrypt the authentication data:
IV = 00 00 00 00 00 00 00 00
host_cryptogram = encrypt(TDES_CBC, S_ENC, IV, host_auth_data)
The last 8 bytes of the encrypted authentication data are the actual host cryptogram that we would send to the card:
EXTERNAL_AUTHENTICATE_data = host_cryptogram[16, 24]
Now we can assemble the EXTERNAL AUTHENTICATE command:
EXTERNAL_AUTHENTICATE = 84 82 03 00 08 | EXTERNAL_AUTHENTICATE_data
We can then calculate the S_MAC key (analoguous to getting the S_ENC above) and the MAC over that command and append it to the command data to get the full EXTERNAL AUTHENTICATE command that can be sent to the card:
EXTERNAL_AUTHENTICATE = 84 82 03 00 10 | EXTERNAL_AUTHENTICATE_data | MAC
Using http://tripledes.online-domain-tools.com/ to reproduce the results of GPJ
Your K_ENC is 404142434445464748494A4B4C4D4E4F
. The online tools does not properly support 2-key-3DES, so you have to convert the key into its 3-key form first:
K_ENC = 404142434445464748494A4B4C4D4E4F4041424344454647
Use this key and a zero IV to encrypt the derivation data (0182001B000000000000000000000000
). You get
S_ENC = fb063cc2e17b979b10e22f82110234b4
In 3-key notation, this is
S_ENC = fb063cc2e17b979b10e22f82110234b4fb063cc2e17b979b
Use this key and a zero IV to encrypt the host authentication data (001b9b95b95e5ebc7f41a9e7193783fa8000000000000000
):
HOST_CRYPTOGRAM = 773e790c91acce3167d99f92c60e2afd133b4ec52c9ed824