· 6 years ago · Jun 28, 2019, 09:08 PM
1if(sMacSessionKey.length == 16) {
2 byte []temp = sMacSessionKey.clone();
3 sMacSessionKey = new byte[24];
4 System.arraycopy(temp,0,sMacSessionKey,0,temp.length);
5 System.arraycopy(temp,0,sMacSessionKey,16,8);
6 }
7
8 byte []cMac = new byte[8];
9 byte []padding = {(byte)0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
10 int paddingRequired = 8 - (apdu.length) %8;
11 byte[] data = new byte[apdu.length + paddingRequired];
12 System.arraycopy(apdu, 0, data, 0, apdu.length);
13 System.arraycopy(padding, 0, data, apdu.length,paddingRequired);
14
15 Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
16
17 Cipher singleDesCipher = Cipher.getInstance("DES/CBC/NoPadding",
18 "SunJCE");
19 SecretKeySpec desSingleKey = new SecretKeySpec(sMacSessionKey, 0, 8,
20 "DES");
21 SecretKey secretKey = new SecretKeySpec(sMacSessionKey, "DESede");
22 // Calculate the first n - 1 block. For this case, n = 1
23 IvParameterSpec ivSpec = new IvParameterSpec(icv);
24 singleDesCipher.init(Cipher.ENCRYPT_MODE, desSingleKey, ivSpec);
25 // byte ivForLastBlock[] = singleDesCipher.doFinal(data, 0, 8);
26
27 int blocks = data.length / 8;
28
29 for (int i = 0; i < blocks - 1; i++) {
30 singleDesCipher.init(Cipher.ENCRYPT_MODE, desSingleKey, ivSpec);
31 byte[] block = singleDesCipher.doFinal(data, i * 8, 8);
32 ivSpec = new IvParameterSpec(block);
33 }
34
35 int offset = (blocks - 1) * 8;
36
37 cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
38 cMac = cipher.doFinal(data, offset, 8);
39
40 ivSpec = new IvParameterSpec(new byte[8]);
41
42 singleDesCipher.init(Cipher.ENCRYPT_MODE, desSingleKey, ivSpec);
43 icvNextCommand = singleDesCipher.doFinal(cMac);
44 System.out.println("icvNextCommand"+Utility.bytesToHex(icvNextCommand, icvNextCommand.length));
45
46 return cMac;
47
48 }