1 回答
TA贡献1829条经验 获得超6个赞
您的 USB 令牌只是调整 3DES 密钥的奇偶校验。每个字节的每个低端位是(三重)DES 的奇偶校验位。
如果最高 7 位相加是偶数则需要设置,如果是奇数则不需要设置。如果将所有位加在一起,最后每个字节都应该具有奇校验。所以第一个带有值0x57or0b0101011_1和的字节在最高位置有 4 位,所以最后一位必须是1- 但它已经被设置,所以不需要调整。第二个字节,0xAF或者0b1010111_1最高位有 5 位,所以最后一位需要是0. 情况并非如此,因此将其调整为0b1010111_0或0xAE。
如果您想拥有相同的值,那么您可以使用 aSecretKeyFactory而不是直接使用随机数生成器来构造您的(三重)DES 密钥。该SecretKeyFactory也将为你调整奇偶-无需自己动手编程。我建议这样做,因为其他实现可能会拒绝位数为偶数的字节(尽管通常调整或忽略位)。正如 James 所指出的,在加密/解密期间(三重)DES 不使用最低位。
这将创建正确编码的三重 DES 密钥(168 位有效,192 位编码)。这些也称为 DES ABC 密钥,因为所有三个 DES 密钥都不同(概率非常高)。
public static SecretKey generate192Bit3DESKey() {
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("DESede");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("DESede functionality is required for Java, but it is missing");
}
// NOTE: this is the effective key size excluding parity bits
// use 112 for two key (ABA) triple DES keys (not recommended)
keyGen.init(168);
// this does adjust parity
SecretKey desABCKey = keyGen.generateKey();
return desABCKey;
}
如果您的数据之后需要调整,您可以使用它(只有一个 for 循环,没有额外的分支):
public static byte[] adjustDESParity(final byte[] keyData) {
for (int i = 0; i < keyData.length; i++) {
// count the bits, and XOR with 1 if even or 0 if already odd
keyData[i] ^= (Integer.bitCount(keyData[i]) % 2) ^ 1;
}
return keyData;
}
添加回答
举报