android DESFire更改默认的PICC主密钥

时间:2016-02-24 10:41:00

标签: android nfc

我正在尝试更改android中的默认主密钥(PICC)。我得到的是INTEGRITY ERROR。以下是我的代码。问题可能在于解密。 DES / 3 DES格式是必要的还是AES很好?

private void authenticate() {
    byte[] rndB = new byte[8];
    byte[] response;
    try {
        response = desfire.transceive(NATIVE_AUTHENTICATION_COMMAND);
        System.arraycopy(response, 1, rndB, 0, 8);

        byte[] command = new byte[17];

        System.arraycopy(DES.gen_sessionKey(rndB), 0, command, 1, 16);
        command[0] = (byte) 0xAF;

        response = desfire.transceive(command);
        changePICC(DES.gen_sessionKey(rndB));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

private void changePICC(byte[] rndB) {
    byte[] response;
    try {

        byte[] command = new byte[26];

        System.arraycopy(DES.gen_piccKey(rndB), 0, command, 2, 24);
        command[0] = (byte) 0xC4;
        command[1] = (byte) 0x00;
        Log.v("command", ByteArrayToHexString(command));
        response = desfire.transceive(command);
        Log.v("auth1 response", ByteArrayToHexString(response));

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

这是关键设置类

public class DES {

private static final int POLYNOMIAL   = 0x8408;
private static final int PRESET_VALUE = 0x6363;

public static byte[] gen_sessionKey(byte[] b) {

    byte[] key = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0,
            (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0,
            (byte) 0x0 };
    byte[] response = decrypt(key, b);
    byte[] rndB = response;
    byte[] rndA = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    byte[] rndAB = new byte[16];
    System.arraycopy(rndA, 0, rndAB, 0, 8);
    rndB = leftShift(rndB);
    rndB = xorBytes(rndA, rndB);
    rndB = decrypt(key, rndB);
    System.arraycopy(rndB, 0, rndAB, 8, 8);
    return rndAB;
}
public static byte[] gen_piccKey(byte[] key) {

    byte[] rndA = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    byte[] rndB = new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF, (byte) 0xFF };
    byte[] rndAB = new byte[24];
    rndA = xorBytes(rndA, rndB);
    Log.v("xor length", String.valueOf(rndB.length));
    byte[] rndABC = iso14443a_crc(rndA);
    byte[] rndABB = iso14443a_crc(rndB);
    Log.v("rnd length", ByteArrayToHexString(rndABC)+"\n"+ByteArrayToHexString(rndABB));
    System.arraycopy(rndA, 0, rndAB, 0, 16);
    System.arraycopy(rndABC, 0, rndAB, 16, 2);
    System.arraycopy(rndABB, 0, rndAB, 18, 2);
    byte[] rndABCD = new byte[] { 0x00, 0x00, 0x00, 0x00}; 
    System.arraycopy(rndABCD, 0, rndAB, 20, 4);
    Log.v("final", ByteArrayToHexString(rndAB));
    rndAB = decrypt(key , rndAB);
    return rndAB;
}

private static byte[] xorBytes(byte[] rndA, byte[] rndB) {
    // TODO Auto-generated method stub
    byte[] b = new byte[rndB.length];
    for (int i = 0; i < rndB.length; i++) {
        b[i] = (byte) (rndA[i] ^ rndB[i]);
    }
    return b;
}


public static byte[] leftShift(byte[] data) {
    // TODO Auto-generated method stub
    byte[] temp = new byte[data.length];
    temp[data.length - 1] = data[0];
    for (int i = 1; i < data.length; i++) {
        temp[i - 1] = data[i];
    }
    return temp;
}

public static byte[] decrypt(byte[] key, byte[] enciphered_data) {

    try {
        byte[] iv = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        SecretKey s = new SecretKeySpec(key, "DESede");
        Cipher cipher;
        cipher = Cipher.getInstance("DESede/CBC/NoPadding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, s, ivParameterSpec);
        byte[] deciphered_data = cipher.doFinal(enciphered_data);
        return deciphered_data;
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

 static byte[] iso14443a_crc(byte[] Data)   // DESFireSAM crc16 do not invert the result
    {
        int  bt;
        int wCrc = 0x6363;
        int j = 0;
        int t8 = 0;
        int t9 = 0;
        int tA = 0;
        int Len = Data.length;
        final int maskB = 0x0000000000000000FF;
        final int maskW = 0x00000000000000FFFF;


        do
        {
            bt = Data[j++]              & maskB;
            bt =  (bt^(wCrc & 0x00FF))  & maskB;
            bt =  (bt^(bt<<4))          & maskB;


            t8 = (bt << 8)          & maskW;
            t9 = (bt<<3)            & maskW;
            tA = (bt>>4)            & maskW;
            wCrc = (wCrc >> 8)^(t8^t9^tA)  & maskW;
        }
        while (j < Len);


        byte[] bb = new byte[2];
        bb[0] = (byte) (wCrc          & maskB);
        bb[1] = (byte) ((wCrc >>8)    & maskB);
        return bb;
}
 private static String ByteArrayToHexString(byte[] inarray) {
        int i, j, in;
        String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
        String out = "";

        for (j = 0; j < inarray.length; ++j) {
            in = (int) inarray[j] & 0xff;
            i = (in >> 4) & 0x0f;
            out += hex[i];
            i = in & 0x0f;
            out += hex[i];
        }
        return out;
    }

请帮我解决这个问题。

0 个答案:

没有答案