根据《AN02105_Mifare generate pwd》文档,用JAVA代码实现了下输入KeyA、KeyB转换成对应的DKeyA、DKeyB,并生成对应的PASSWORD的过程。
这块网上现成的JAVA代码比较少,踩了几天坑,现在记录下踩坑的经历。
踩坑一:Triple-DES算法
需按照以下配置进行:
public static String desEncrypt(byte[] key, byte[] data) {
return performDes(Cipher.ENCRYPT_MODE, key, data);
}
public static String desDecrypt(byte[] key, byte[] data) {
return performDes(Cipher.DECRYPT_MODE, key, data);
}
protected static String performDes(int opMode, byte[] key, byte[] data) {
try {
byte[] iv = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Cipher des = Cipher.getInstance("DESede/CBC/NoPadding");
SecretKeyFactory desKeyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey desKey = desKeyFactory.generateSecret(new DESedeKeySpec(key));
des.init(opMode, desKey, new IvParameterSpec(iv));
byte[] ret = des.doFinal(iv);
ret = reverseByteArray(ret);
return byteArrayToHexStr(ret);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
关键是初始的输入字段、CBC算法以及输出结果补全的规则,即DESede/CBC/NoPadding配置。
踩坑二:KeyA、KeyB 6字节转8字节
需要严格按照规范中的逻辑来实现,当时网上找了段C语言的代码,存在问题,最终实现如下。
for (int i = 0; i < keyA.length; i++) {
//填写dKeyA的前6个字节
if (i < 6) {
dKeyA[i] = (byte) ((keyA[i] << 1) & 0xff);
}
//填写dKeyA的第7个字节
if (i < 6) {
dKeyA[6] |= ((keyA[i] >> 7) & 1) << (6 - i);
}
}
//填写dKeyA的第8个字节
dKeyA[7] = 0x00;
for (int i = 0; i < keyB.length; i++) {
//填写dKeyA的第2个字节
if (i < 6) {
dKeyB[1] |= ((keyB[i] >> 7) & 1) << (i + 1);
}
//填写dKeyA的后6个字节
if (i < 6) {
dKeyB[2 + i] = (byte) ((keyB[i] << 1) & 0xff);
}
}
//填写dKeyA的第1个字节
dKeyB[0] = 0x00;
踩坑三:DKeyA、DKeyB、PASSWORD翻转
这点最坑,就是输出的DKeyA、DKeyB、PASSWORD这三个字段都需要进行字节前后翻转后输出,不然无法生成跟规范中一致的结果。规范里也没有特别明确的写到这一点,在实现的时候需要多加注意。附上字节翻转的代码。
public static byte[] reverseByteArray(byte[] bytesOriginal) {
byte[] rst = new byte[bytesOriginal.length];
for (int i = 0; i < bytesOriginal.length; i++) {
rst[bytesOriginal.length - i - 1] = bytesOriginal[i];
}
return rst;
}
文章介绍了使用JAVA实现Mifare文档中KeyA和KeyB到DKeyA和DKeyB的转换,以及生成PASSWORD的过程,重点涉及Triple-DES的CBC无填充加密模式,以及字节处理和翻转的细节。在转换和加密过程中,作者遇到了初始字段配置、6字节到8字节转换和字节顺序翻转等问题,并提供了相应的解决方案。
6073

被折叠的 条评论
为什么被折叠?



