通过Java密码体系结构和一些代码示例,我学习了如何使用Mac类来计算Mac:
请找到以下代码以计算MAC:
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(<secretKeyHere>);
byte[] macHash = mac.doFinal(<encryptedTextHere>);
但是实际上我正在寻找一种使用ISO 9797-1算法3(零售MAC)和填充1(如果需要的话,在数据末尾添加值0的位,直到填充的数据为n的倍数,其中n是DES密码的块大小,即8)。
任何人都可以在Java中建议代码示例吗?
答案 0 :(得分:1)
async loading包含一个BouncyCastle,用于计算“零售MAC”。
function api1 () {
return fetch1().then(v =>{
console.log("Api1", v);
return v;
);
}
要使用可选零填充,您需要自己执行填充,就像Bouncy Castle总是 填充一样,即使执行定义不明确的零填充也是如此。
public byte[] getRetailMAC(byte[] key, byte[] data) {
BlockCipher cipher = new DESEngine();
Mac mac = new ISO9797Alg3Mac(cipher, 64, new ISO7816d4Padding());
KeyParameter keyP = new KeyParameter(key);
mac.init(keyP);
mac.update(data, 0, data.length);
byte[] out = new byte[8];
mac.doFinal(out, 0);
return out;
}
请注意,这种填充不能区分以一个或多个零值字节结尾的消息(如果8字节的块数保持不变)。因此,对于仅预定义字节数的消息来说是不安全的。
更新:
手动填充是不必要的,因为此填充模式(规范中的类型1)实际上是默认填充模式,并且是在MAC实现中执行的。因此,当不提供 any 填充时,您会得到此信息。请注意,这与提供public byte[] getRetailMAC(byte[] key, byte[] data) {
int macSizeBits = 64;
BlockCipher cipher = new DESEngine();
Mac mac = new ISO9797Alg3Mac(cipher, macSizeBits);
KeyParameter keyP = new KeyParameter(key);
mac.init(keyP);
mac.update(data, 0, data.length);
// perform padding manually - NOT REQUIRED, SEE UPDATE
int n = cipher.getBlockSize();
int zeroPaddingRequired = n - (data.length + n - 1) % n - 1;
for (int i = 0; i < zeroPaddingRequired; i++) {
mac.update((byte) 0x00);
}
byte[] out = new byte[macSizeBits / Byte.SIZE];
mac.doFinal(out, 0);
return out;
}
不同,因为最后一个总是填充。