java - I got 0x1E error (INTEGRITY_ERROR) while change DESFire master key.What are my mistakes?And How can I resolve? -
whole update1: see question again.
i working desfire cards .i decide change defult master key of picc.
(i authenticate master key 8 byte 0x00 successfully)
1- defult master key 8 byte of zero.it 00 00 00 00 00 00 00 00.
2-new master key choosed 16 byte.
it is:
byte[] newpicckey= new byte[]{(byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66, (byte)0x77 ,(byte)0x88, (byte)0x12, (byte)0x23, (byte)0x34 ,(byte)0x45 , (byte)0x56, (byte)0x67, (byte)0x78 ,(byte)0x89}; 3- authenticate old master key( still not changed , still 8 byte of zero.) successfully. random numbers :
random = 8 byte number
random b = 8 byte number
4 - create session key each time using random , random b : session key = first 4 byte of random + first 4 byte of random b
//fill sessionkey randoma , randomb for(int i=0; i<4; i++) sessionkey[i] = randoma[i]; for(int i=4; i<8; i++) sessionkey[i] = randomb[i-4]; 5 - create crc16 new master key bellow method . result : d8 ec (the new picc master key 16 byte? or must 8 byte? way choosed 16 byte value new master key)
public class crc16 { public static short crc16(byte[] buffer, short offset, short len) { short crctmp = 0x6363; (int = 0; < len; ++i) { short temp = (short)(buffer[offset + i] ^ crctmp); temp = (short)((temp ^ (temp << 4)) & 0xff); crctmp = (short)(((crctmp >> 8) & 0xff) ^ (temp << 8) ^ (temp << 3) ^ (temp >> 4)); } return crctmp; } } 6 - create ew picc key crc , padding(deciphered)
byte[] newpicckey_deciphered = new byte[]{(byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66, (byte)0x77 ,(byte)0x88, (byte)0x12, (byte)0x23, (byte)0x34 ,(byte)0x45 , (byte)0x56, (byte)0x67, (byte)0x78 ,(byte)0x89, (byte)0x00 , (byte)0x00, (byte)0x00 ,(byte)0x00 ,(byte)0x00 , (byte)0x00 ,(byte)0x00 ,(byte)0x00 }; txtnewpicckeydeciphered.settext(utils.bytestohex(newpicckey_deciphered)); 7- calculate crc16 , add new key:
short res = crc16_3.crc16(newpicckey, (short)0, (short)16); newpicckey_deciphered[16] = (byte) (res & 0xff); newpicckey_deciphered[17] = (byte) ((res >> 8) & 0xff); 8 - enciphered above new master key bellow method , got 24 byte enciphered :
byte[] iv1=new byte[]{(byte)0x00 , (byte)0x00 , (byte)0x00 , (byte)0x00 , (byte)0x00 , (byte)0x00 , (byte)0x00 , (byte)0x00 }; byte[] newpicckeyenciphered = new byte[24]; //.............................. byte[] block1 = new byte[]{(byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44, (byte)0x55, (byte)0x66, (byte)0x77 ,(byte)0x88}; byte[] block2 = new byte[]{ (byte)0x11, (byte)0x22, (byte)0x33 ,(byte)0x44 , (byte)0x55, (byte)0x66, (byte)0x77 ,(byte)0x88}; byte[] block3 = new byte[]{(byte)0x00 , (byte)0x00, (byte)0x00 ,(byte)0x00 ,(byte)0x00 , (byte)0x00 ,(byte)0x00 ,(byte)0x00}; block3[0] = newpicckey_deciphered[16]; block3[1] = newpicckey_deciphered[17]; try { cipher cipher = cipher.getinstance("des/ecb/nopadding"); secretkeyfactory deskeyfact = secretkeyfactory.getinstance("des"); deskeyspec deskeyspec = new deskeyspec(sessionkey); secretkey s = deskeyfact.generatesecret(deskeyspec); cipher.init(cipher.decrypt_mode, s); byte[] r1 = new byte[8]; r1 =utils.doxortwobytearray(block1, iv1); byte[] r2 = new byte[8]; r2 = cipher.dofinal(r1, 0, 8); //............... byte[] r3 = new byte[8]; r3 =utils.doxortwobytearray(block2, r2); byte[] r4 = new byte[8]; r4 =cipher.dofinal(r3, 0, 8); //................ byte[] r5 = new byte[8]; r5 =utils.doxortwobytearray(block3, r4); byte[] r6 = new byte[8]; r6 =cipher.dofinal(r5, 0, 8); for(int i=0; i<8;i++) newpicckeyenciphered[i] = r2[i]; for(int i=8; i<16;i++) newpicckeyenciphered[i] = r4[i-8]; for(int i=16; i<24;i++) newpicckeyenciphered[i] = r6[i-16]; } catch(exception e) { e.printstacktrace(); } here class des used @ enciphering :
public class des { public static byte[] dodecryptdata(byte[] originaldata,byte[]key , int sizekey , byte[] iv , int sizeiv) { byte[] masterkeybytes =new byte[sizekey]; masterkeybytes = key; byte[] ivbytes = new byte[sizeiv]; ivbytes = iv; byte[] enciphereddata=new byte[sizeiv]; try{ deskeyspec deskeyspec = new deskeyspec(masterkeybytes); secretkeyfactory deskeyfact = secretkeyfactory.getinstance("des"); secretkey s = deskeyfact.generatesecret(deskeyspec); cipher alicecipher = cipher.getinstance("des/cbc/nopadding"); alicecipher.init(cipher.decrypt_mode, s, new ivparameterspec(ivbytes)); enciphereddata= alicecipher.dofinal(originaldata); return enciphereddata; } catch(exception e) { log.e("error", "111"+e.tostring()); } return null; } 9- , fill parameter byte array , send instruction(c4)
byte[] cmd = new byte[]{(byte)0x00 , (byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 }; //fill cmd for(int i=1 ;i<cmd.length ; i++) cmd[i] = newpicckeyenciphered[i -1]; try { responsechangekey = isodep.transceive(utils.wrapmessage((byte)0xc4, cmd)); } catch (ioexception e1) { // todo auto-generated catch block e1.printstacktrace(); } catch (exception e1) { // todo auto-generated catch block e1.printstacktrace(); } and here utils class:
public class utils { public static byte[] wrapmessage (byte command, byte[] parameters) throws exception { bytearrayoutputstream stream = new bytearrayoutputstream(); stream.write((byte) 0x90); stream.write(command); stream.write((byte) 0x00); stream.write((byte) 0x00); if (parameters != null) { stream.write((byte) parameters.length); stream.write(parameters); } stream.write((byte) 0x00); byte[] b = stream.tobytearray(); return b; } } i @ last step (sending apdu changing master key card) recieved exception 0x1e error, means integrity error :crc or mac not match data padding bytes not valid. how can perform changing key correctly ? necessaryfor me.thanks.
- desfire cards uses little different crc16 yours. initial value crc16
0xffff, desfire expects0x6363. may cause troubles integrity error. - i see no dec/cbc encryption using decryption of
newpicckey_decipheredarray. have use decryption mode instead of encryption mode when encrypting (although seems weird). means:
alicecipher.init(cipher.decrypt_mode, s, new ivparameterspec(ivbytes));
and because of fact, cbc mode of decryption different cbc mode encryption, have implement own cbc mode , use alicecipher 1 block correct iv.
Comments
Post a Comment