How can I check INITIALIZE UPDATE and EXTERNAL AUTHENTICATE correctness?

Abraham picture Abraham · Jun 7, 2014 · Viewed 7.4k times · Source

enter image description here

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?

Answer

Michael Roland picture Michael Roland · Jun 7, 2014

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

Update

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