ARPC generation
Posted: Wed Jun 07, 2017 9:25 am
Hi,
Does anyone knows ARPC generation in java card?
Thanks in advance...!!
Deepansh
Does anyone knows ARPC generation in java card?
Thanks in advance...!!
Deepansh
JavaCardOS - JavaCardForum
http://www.javacardos.com/javacardforum/
http://www.javacardos.com/javacardforum/viewtopic.php?f=15&t=1208
[2017-06-08 10:51:15] BP-Tools - Cryptographic Calculator is ready
********************
[2017-06-08 10:51:17]
EMV Cryptography: ARPC generation finished
****************************************
ARPC Method: 1
Response Code: Y3: Unable to go online (offline approved)
Session key: 7CBA97ABD6CB6E0B29A7457A7332DFC4
Transaction Cryptogram:0C25134A77B0F6B3
----------------------------------------
ARPC generated: 47CA7F6274A9FCB1
8.2.1 ARPC Method 1
ARPC Method 1 for the generation of an 8-byte ARPC consists of applying the
Triple-DES algorithm as specified in Annex B1.1 to:
the 8-byte ARQC generated by the ICC as described in section 8.1
the 2-byte Authorisation Response Code (ARC)
using the 16-byte Application Cryptogram Session Key SKAC (see section 8.1) in
the following way:
1. Pad the 2-byte ARC with six zero bytes to obtain the 8-byte number
X := (ARC || '00'|| '00' || '00' || '00' || '00' || '00')
2. Compute Y: = ARQC ^ X.
3. The 8-byte ARPC is then obtained by
ARPC := DES3(SKAC)[Y]
Code: Select all
switch (buf[ISO7816.OFFSET_INS])
{
case (byte) 0x00:
apdu.setIncomingAndReceive();
key.setKey(buf, ISO7816.OFFSET_CDATA);
break;
case (byte) 0x02:
short dataLen2 = apdu.setIncomingAndReceive();
// Note: Receive more data bytes if exists with apdu.receiveBytes().
Cipher cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
cipher.init(key, Cipher.MODE_ENCRYPT);
short resultLen2 = cipher.doFinal(buf, ISO7816.OFFSET_CDATA, dataLen2, buf, (short) 0);
apdu.setOutgoingAndSend((short) 0, resultLen2);
JCSystem.requestObjectDeletion();
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
>> /select 112233445500
>> 00 A4 04 00 06 11 22 33 44 55 00 00
<< 90 00
>> /send 00000000107CBA97ABD6CB6E0B29A7457A7332DFC4
>> 00 00 00 00 10 7C BA 97 AB D6 CB 6E 0B 29 A7 45 7A 73 32 DF C4
<< 90 00
>> /send 00020000085516134A77B0F6B3
>> 00 02 00 00 08 55 16 13 4A 77 B0 F6 B3
<< 47 CA 7F 62 74 A9 FC B1 90 00
Code: Select all
public void generateSecondAC(APDU apdu, byte[] apduBuffer) {
short dataLen = apduBuffer[OFFSET_LC];
Util.arrayCopy(apduBuffer, (short) 5, onlineARPC, (short) 0, (short) 8);
Util.arrayCopy(apduBuffer, (short) 0x0D, responseCode, (short) 0, (short) 2);
byte[] Y = new byte[8];
// XOR between ARQC and Response Code as per mentioned in ARPC method 1 EMV book 2 (8.2.1)
Y = xor(chipMAC, responseCode);
Cipher cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
cipher.init(theCrypto.sk, Cipher.MODE_ENCRYPT);
short resultLen = cipher.doFinal(Y, (short) 0, (short) (8), apduBuffer, (short) (dataLen + 10));
apdu.setOutgoingAndSend((short) (dataLen + 10), (short) (resultLen));
JCSystem.requestObjectDeletion();
}
private static byte[] padding(byte[] data) {
// int dataLen = data.length;
// int paddingSize = (8 - (dataLen + 1) % 8);
// return fillRight(data, (byte) 0x00, paddingSize);
byte[] t = new byte[ (short) (data.length - data.length % 8 + 8)];
Util.arrayCopy(data, (short) 0, t, (short) 0, (short) data.length);
for (short i = (short) data.length; i < t.length; i++)
t[i] = (byte) (i == data.length ? 0x00 : 0x00);
data = t;
return data;
}
deepanshsinghal wrote:Code: Select all
public void generateSecondAC(APDU apdu, byte[] apduBuffer) {
short dataLen = apduBuffer[OFFSET_LC];
Util.arrayCopy(apduBuffer, (short) 5, onlineARPC, (short) 0, (short) 8);
Util.arrayCopy(apduBuffer, (short) 0x0D, responseCode, (short) 0, (short) 2);
byte[] Y = new byte[8];
// XOR between ARQC and Response Code as per mentioned in ARPC method 1 EMV book 2 (8.2.1)
Y = xor(chipMAC, responseCode);
Cipher cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
cipher.init(theCrypto.sk, Cipher.MODE_ENCRYPT);
short resultLen = cipher.doFinal(Y, (short) 0, (short) (8), apduBuffer, (short) (dataLen + 10));
apdu.setOutgoingAndSend((short) (dataLen + 10), (short) (resultLen));
JCSystem.requestObjectDeletion();
}
private static byte[] padding(byte[] data) {
// int dataLen = data.length;
// int paddingSize = (8 - (dataLen + 1) % 8);
// return fillRight(data, (byte) 0x00, paddingSize);
byte[] t = new byte[ (short) (data.length - data.length % 8 + 8)];
Util.arrayCopy(data, (short) 0, t, (short) 0, (short) data.length);
for (short i = (short) data.length; i < t.length; i++)
t[i] = (byte) (i == data.length ? 0x00 : 0x00);
data = t;
return data;
}
can you check what i am missing?
deepanshsinghal wrote:Code: Select all
public void generateSecondAC(APDU apdu, byte[] apduBuffer) {
short dataLen = apduBuffer[OFFSET_LC];
Util.arrayCopy(apduBuffer, (short) 5, onlineARPC, (short) 0, (short) 8);
Util.arrayCopy(apduBuffer, (short) 0x0D, responseCode, (short) 0, (short) 2);
byte[] Y = new byte[8];
// XOR between ARQC and Response Code as per mentioned in ARPC method 1 EMV book 2 (8.2.1)
Y = xor(chipMAC, responseCode);
Cipher cipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
cipher.init(theCrypto.sk, Cipher.MODE_ENCRYPT);
short resultLen = cipher.doFinal(Y, (short) 0, (short) (8), apduBuffer, (short) (dataLen + 10));
apdu.setOutgoingAndSend((short) (dataLen + 10), (short) (resultLen));
JCSystem.requestObjectDeletion();
}
private static byte[] padding(byte[] data) {
// int dataLen = data.length;
// int paddingSize = (8 - (dataLen + 1) % 8);
// return fillRight(data, (byte) 0x00, paddingSize);
byte[] t = new byte[ (short) (data.length - data.length % 8 + 8)];
Util.arrayCopy(data, (short) 0, t, (short) 0, (short) data.length);
for (short i = (short) data.length; i < t.length; i++)
t[i] = (byte) (i == data.length ? 0x00 : 0x00);
data = t;
return data;
}
can you check what i am missing?
UNKNwYSHSA wrote:Can you give me the APDU you sent?
Code: Select all
>> /select A0000000494F434C435051
>> 00 A4 04 00 0B A0 00 00 00 49 4F 43 4C 43 50 51 00
<< 90 00
>> /send 80AE40002B00000000031400000000000003560420008000035616080200549E74AD22000000000000000000003F0002
>> 80 AE 40 00 2B 00 00 00 00 03 14 00 00 00 00 00 00 03 56 04 20 00 80 00 03 56 16 08 02 00 54 9E 74 AD 22 00 00 00 00 00 00 00 00 00 00 3F 00 02 00
<< 2B BA 1E CD 05 17 85 5A 90 00
>> /send 80AE20000A980B4B43FF9B9F510000
>> 80 AE 20 00 0A 98 0B 4B 43 FF 9B 9F 51 00 00
<< 2D AD 26 F6 0A 7D A8 66 90 00
Code: Select all
Y = xor(chipMAC, responseCode);
UNKNwYSHSA wrote:1 Following your code:Code: Select all
Y = xor(chipMAC, responseCode);
What is the chipMAC?
2 The response code is 2 bytes, it is hex value from "00" to "Z3", it can not be 0000. Hex value of "00" is 3030.
deepanshsinghal wrote:UNKNwYSHSA wrote:1 Following your code:Code: Select all
Y = xor(chipMAC, responseCode);
What is the chipMAC?
2 The response code is 2 bytes, it is hex value from "00" to "Z3", it can not be 0000. Hex value of "00" is 3030.
Chipmac is ARQC that is generating earlier