下面是一个例子的java代码作为MF0ICU2/MIFARE Ultralight C - Contactless ticket IC document(章节7.5.5 - 3DES认证,第15页)中所描述来执行超轻-C认证:
public void authenticate(byte[] key) throws CardException {
System.out.println("AUTHENTICATE");
byte[] encRndB = transmitRaw(new byte[] { 0x1A, 0x00 });
if((encRndB.length!=9)||(encRndB[0]!=AF)) {
throw new RuntimeException("Invalid response!");
}
encRndB=Arrays.copyOfRange(encRndB, 1, 9);
System.out.println(" - EncRndB: " + toHex(encRndB));
byte[] rndB = desDecrypt(key, encRndB);
System.out.println(" - RndB: " + toHex(rndB));
byte[] rndBrot = rotateLeft(rndB);
System.out.println(" - RndBrot: " + toHex(rndBrot));
byte[] rndA = new byte[8];
generateRandom(rndA);
System.out.println(" - RndA: " + toHex(rndA));
byte[] encRndArotPrime = transmitRaw(ArrayUtils.addAll(new byte[] {AF}, desEncrypt(key, ArrayUtils.addAll(rndA, rndBrot))));
if((encRndArotPrime.length!=9)||(encRndArotPrime[0]!=0x00)) {
throw new RuntimeException("Invalid response!");
}
encRndArotPrime=Arrays.copyOfRange(encRndArotPrime, 1, 9);
System.out.println(" - EncRndArot': " + toHex(encRndArotPrime));
byte[] rndArotPrime = desDecrypt(key, encRndArotPrime);
System.out.println(" - RndArot': " + toHex(rndArotPrime));
if(!Arrays.equals(rotateLeft(rndA), rndArotPrime)) {
throw new RuntimeException("Card authentication failed");
}
}
protected static SecureRandom rnd = new SecureRandom();
protected static void generateRandom(byte[] rndA) {
rnd.nextBytes(rndA);
}
protected byte[] desEncrypt(byte[] key, byte[] data) {
return performDes(Cipher.ENCRYPT_MODE, key, data);
}
protected byte[] desDecrypt(byte[] key, byte[] data) {
return performDes(Cipher.DECRYPT_MODE, key, data);
}
private byte[] iv = new byte[8];
protected byte[] performDes(int opMode, byte[] key, byte[] data) {
try {
Cipher des = Cipher.getInstance("DESede/CBC/NoPadding");
SecretKeyFactory desKeyFactory = SecretKeyFactory.getInstance("DESede");
Key desKey = desKeyFactory.generateSecret(new DESedeKeySpec(ArrayUtils.addAll(key, Arrays.copyOf(key, 8))));
des.init(opMode, desKey, new IvParameterSpec(iv));
byte[] ret = des.doFinal(data);
if(opMode==Cipher.ENCRYPT_MODE) {
iv=Arrays.copyOfRange(ret, ret.length-8, ret.length);
} else {
iv=Arrays.copyOfRange(data, data.length-8, data.length);
}
return ret;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidKeySpecException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
}
}
protected static byte[] rotateLeft(byte[] in) {
return ArrayUtils.add(Arrays.copyOfRange(in, 1, 8), in[0]);
}
注意:此代码使用Apache Commons Lang。
来源
2017-06-19 21:49:16
vlp
我在恩智浦应用笔记AN0945中找到了非常有益的实例,可用于调试我自己的代码。 –
太好了,谢谢!我错过了,因为它是DESFire文档,我没有注意到DocStore中的文件夹。我刚下载,看起来很有希望。再次感谢 - 我非常感谢您的意见。 –
NFCGuy - 您(或您认识的任何人)是否使用Android设备成功地通过Ultralight-C进行了端到端身份验证? –