Hello!
Does anyone know the algorithm VISA and MasterCard uses to generate the ARQC? I know they have different algorithms, and I didn't find anything detailed enough the verify a generated ARQC.
For example, http://www.emvlab.org/cryptogram/ provides an online form - but the result dosen't match. It may be that I had the wrong values for transaction data, but there is also no option for the algorithm. I've also tried the Thales Simulator, but the Implementation seems broken.
The JCESecurityModule in jPOS doesn't implement the verifyARQCImpl-Method, but that's exactly what I'm looking for.
The Thales sim generates the same ICC Master Key as jPOS, but I could not find where session key derivation takes place in the Thales sim sources.
The emvlab.org provides no sources at all.
My major problem seems to build valid input data. Does anyone know the exact data elements (format, values, ...) used by MasterCard and or VISA for Application Cryptogram generation?
Transaction Amount |
Other Amount |
Terminal Country Code |
Terminal Verification Results |
Transaction Currency Code |
Transaction Date |
Transaction Type |
Unpredictable Number |
Application Interchange Profile |
Application Transaction Counter |
Card Verification Results |
public static void main(String[] args) throws Exception {
byte[] amountAuhtorised = ISOUtil.hex2byte("000000001000");
byte[] amountOther = ISOUtil.hex2byte("000000000000");
byte[] terminalCountryCode = ISOUtil.hex2byte("0040");
byte[] terminalVerificationResults = ISOUtil.hex2byte("8000048000");
byte[] transactionCurrencyCode = ISOUtil.hex2byte("0978");
byte[] transactionDate = ISOUtil.hex2byte("100514");
byte[] transactionType = ISOUtil.hex2byte("01");
byte[] unpredictableNumber = ISOUtil.hex2byte("2E13374C");
byte[] applicationInterchangeProfile = ISOUtil.hex2byte("1800");
byte[] applicationTransactionCounter = ISOUtil.hex2byte("0014");
byte[] cvmResults = ISOUtil.hex2byte("020300");
JCESecurityModule module = new JCESecurityModule("secret.lmk", BouncyCastleProvider.class.getCanonicalName());
byte[] iMk = ISOUtil.hex2byte("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
byte[] panpsn = JCESecurityModule.formatPANPSN("1234567890123456", null, MKDMethod.OPTION_A);
System.out.println("PAN: " + ISOUtil.byte2hex(panpsn));
Key key = new SecretKeySpec(iMk, "DESede");
Key iccMk = module.deriveICCMasterKey(key, panpsn);
System.out.println("iccMk: " + ISOUtil.byte2hex(iccMk.getEncoded()));
Key sKey = module.deriveCommonSK_SM(iccMk, applicationTransactionCounter);
System.out.println("sKey: " + ISOUtil.byte2hex(sKey.getEncoded()));
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
outStream.write(amountAuhtorised);
outStream.write(amountOther);
outStream.write(terminalCountryCode);
outStream.write(terminalVerificationResults);
outStream.write(transactionCurrencyCode);
outStream.write(transactionDate);
outStream.write(transactionType);
outStream.write(unpredictableNumber);
outStream.write(applicationInterchangeProfile);
outStream.write(applicationTransactionCounter);
outStream.write(cvmResults);
outStream.write(ISOUtil.hex2byte("80"));
byte[] data = module.paddingISO9797Method2(outStream.toByteArray());
byte[] result = module.calculateMACISO9797Alg3(sKey, data);
System.out.println(ISOUtil.byte2hex(result));
}
byte[] iMk = ISOUtil.hex2byte("9E15204313F7318ACB79B90BD986AD29");
byte[] panpsn = JCESecurityModule.formatPANPSN("5413330089010012", null, MKDMethod.OPTION_A);
PAN: 1333008901001200
iccMk: 4ac445704620c12ab954492f6e5e5efd4ac445704620c12a
sKey: a8fb5816453b8392f13885c72604ecc4a8fb5816453b8392
4abeb01ea40719dc
// Key sKey = module.deriveCommonSK_SM(iccMk, applicationTransactionCounter);
Key sKey = module.deriveSK_VISA(iccMk, applicationTransactionCounter);
System.out.println("sKey: " + ISOUtil.byte2hex(sKey.getEncoded()));
sKey: 4ac445704620c13eb954492f6e5ea1164ac445704620c13e
Key sKey = module.deriveCommonSK_SM(iccMk, applicationTransactionCounter);
Data (before paddingISO9797Method2): 000000001000000000000000004080000480000978100514012e13374c1800001402030080
Data (after paddingISO9797Method2): 000000001000000000000000004080000480000978100514012e13374c1800001402030080800000
A note to the output values, the expected Application Cryptogram is 0x4B68C1D3849032C7 (generated by M/Chip TIP Test card), 0x4abeb01ea40719dc is the (wrong) result my program generates. Here's the Hex-Dump of the transaction data as requested:
Data (before paddingISO9797Method2): 000000001000000000000000004080000480000978100514012e13374c1800001402030080
Data (after paddingISO9797Method2): 000000001000000000000000004080000480000978100514012e13374c1800001402030080800000
e29db34f0be7d44e != 4B68C1D3849032C7
Hello!
Does anyone know the algorithm VISA and MasterCard uses to generate the ARQC? I know they have different algorithms, and I didn't find anything detailed enough the verify a generated ARQC. For example, http://www.emvlab.org/cryptogram/ provides an online form - but the result dosen't match. It may be that I had the wrong values for transaction data, but there is also no option for the algorithm. I've also tried the Thales Simulator, but the Implementation seems broken. The JCESecurityModule in jPOS doesn't implement the verifyARQCImpl-Method, but that's exactly what I'm looking for.
Best regards
Billie
iMK: 9E 15 20 43 13 F7 31 8A CB 79 B9 0B D9 86 AD 29
PAN: 5413330089010012
820218008407A0000000041010950580000480009A031005149C01015F2A0209789F02060000000010009F090200029F10120212A0000F240000000000000000000000FF9F1A0200409F1E0833533459524D56469F26084B68C1D3849032C79F2701809F33036040209F34030203009F3501149F360200149F37042E13374C9F41030015209F53015A
PAN: 4761739001010176
MDK A: 2315 208C 9110 AD40
MDK B: 2315 208C 9110 AD40
820208008407A0000000031010950580800080009A031002239C01015F2A0209789F02060000000010009F090201409F100706000C03A010009F1A0200409F1E0833533459524D56469F26086E32F3724A2EDE179F2701809F33036040209F34033F00009F3501149F360200069F37043F2C0E4F9F4103000188
020300
) is wrong - 020300
are the CVM results. The CVR should be encoded in the Issuer Application Data (9F10), but I don't know how exactly. I tried some variants, but still no match. Maybe we are missing some information to reproduce the ARQC.5413330089010012
should be, according to the documentation, the following:The coding of Issuer Application Data is described in Appendix A, VIS Data Element Tables. For Cryptogram Version Numbers 10
and 18 (CVN 10 and CVN 18), it contains the following data concatenated in the order specified:The length indicator, DKI, Cryptogram Version Number, and CVR are mandatory, while the Issuer Discretionary Data is optional.
- (1 byte) Length Indicator
- (1 byte) Derivation Key Index (DKI)
- (1 byte) Cryptogram Version Number
- (4 byte) Card Verification Results (CVR)
- (rest if any) Issuer Discretionary Data (optional)
9F100706000C03A01000
9F10 07
06 - length indicator
00 - deriv. key index
0C - CVN12 :(
03A01000 - 4 CVR bytes
CVN 12 and CVN 50 through 59 have been made available to designate issuer proprietary cryptogram processing. They may be used by issuers that do not wish to implement the key management or issuer host authentication processing associated with CVN 10 or CVN 18 in the early stages of migration, or by issuers that want to support an issuer-proprietary cryptogram.Commonly used for VSDC are CVN10 and CVN18 where for ARQC verification:
Issuer Application Data for M/Chip Select 4
- (1 byte) Key Derivation Index
- (1 byte) Cryptogram Version Number
For M/Chip use 80 + zeroes padding for data. Try with SKDMethod.MCHIP
- (6 bytes) Card Verification Results
- (2 bytes) DAC/ICC Dynamic Number
- (8 bytes) Plaintext/Encrypted Counters (optional)
9F10120212A0000F240000000000000000000000FF
9F10 12
02 - Key Derivation Index
12 - Cryptogram Version Number
A0000F240000 - Card Verification Results
0000 - DAC/ICC Dynamic Number
00000000000000FF - Plaintext/Encrypted Counters
A0000F240000
'Hi guys,
I´m developing a simulator software for a great company in Brazil and I´m facing some lack of information from the depto who has hired me to develop the SW.
I need some support from you, because I am running out of ideas to overcome the following issue. One of the information is about the cryptogram version in order to guide me to the methods for ICC Master Key and Session Key derivations. From the message request I got the following IAD (9F10): '0FA501A030F8000000000000000000000F000000000000000000000000000000' My reasoning is that according to the IAD, whose format is A, the cryptogram version is 5, and therefore I infer from the EMV 4.2 Book 2 (Annex A1.4) I should use the methods described there to derive MKac and SKac. Am I right about my interpretation of the IAD ? Is the cryptogram version 5 ? I´ve been using BP-Tool to help me to calculate ARQC and I´ve already chosen EMV 4.2 method to calculate it, but I haven´t it got right yet. The ARQC calculated is different from 9F26.
I don´t know which variables are wrong: method to derive the keys, IMKac, or data. My first step is having the method surely clarified, then I will skip to the next doubt until get the ARQC done. My idea would be start coding and using JPOS library when I fill the gaps. Thanks a lot and I´d appreciate any comments or ideas.
Marcos