02 October 2011

CMAC for JCOP

CMAC
New version since Aug 2010 - everything works! thanks jcManager & braicu




        public static byte[] generateMAC_SCP02(byte[] iv, byte[] data) throws Exception {
                byte cMac[] = null;
if (data.length < 5)
                {
                    print("\n MAC data.length  < 5 \n");
                    return cMac;
                }
                int z = data[4] & 0xFF;
z = z + 8;
//padding
int dz = data.length+1;
while ((dz & 7)!=0) {
dz++;
}


byte[] dataWithPAD = new byte[dz];
int dsub = dz - 8;


System.arraycopy(data,     0, dataWithPAD,           0, data.length);
                dataWithPAD[data.length] = (byte)0x80;
dataWithPAD[4] = (byte)z;   //modify Lc with C-MAC length


SecretKeySpec desSingleKey = new SecretKeySpec(S_MAC_24,0, 8,"DES");
Cipher singleDesCipher = Cipher.getInstance("DES/CBC/NoPadding");
byte ivc[] = null;
IvParameterSpec ivSpec = new IvParameterSpec(iv);
                if (dsub > 0)                   // try as 1 op
                {
                    byte[] head = new byte [dsub];  // care dsub may = 0
                    System.arraycopy(dataWithPAD,0,head,0,dsub);
             singleDesCipher.init(Cipher.ENCRYPT_MODE, desSingleKey, ivSpec);
   ivc = singleDesCipher.doFinal(head); //Final<<<<<<<<<<<<
   ivSpec = new IvParameterSpec(ivc);
                }




SecretKeySpec desKey = new SecretKeySpec(S_MAC_24, "DESede");
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding", "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, desKey, ivSpec);
cMac = cipher.doFinal(dataWithPAD, dsub, 8); //Final<<<<<<<<<<<<
return cMac;
}




I can even change keys (sometimes, on some cards! - there may be something about new and old key version that needs to be done right.. braicu just assumes old version = 1)

No comments:

Post a Comment