我正在 Java 中使用 AES/CTR/NoPadding
使用恒定 key 和随机 IV 来加密我的消息。
我计划将 IV 添加到密文前面,然后对其进行 Base64 编码。
现在有一个问题困扰着我。可以有多个 IV
+ 密文组合来生成我的原始消息。这不是问题吗?另外,发送 IV 是否安全(即在密文前面/附加)或者我应该遵循一些程序?
我对密码学比较陌生,所以如果这是一个非常简单的问题,请原谅我。我找不到任何令人满意的答案。
编辑:
public static String encrypt(String message) {
try {
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
byte[] iv = generateRandomIV();
cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, new IvParameterSpec(iv));
byte[] cipherText = cipher.doFinal(message.getBytes("utf-8"));
return DatatypeConverter.printBase64Binary(concat(iv, cipherText));
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String encryptedMessage) {
try {
byte[] bytes = DatatypeConverter.parseBase64Binary(encryptedMessage);
byte[] iv = getIV(bytes);
byte[] cipherText = getCipherText(bytes);
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, new IvParameterSpec(iv));
return new String(cipher.doFinal(cipherText));
} catch (Exception ex) {
ex.printStackTrace();
return encryptedMessage;
}
}
private static byte[] getIV(byte[] bytes) {
return Arrays.copyOfRange(bytes, 0, 16);
}
private static byte[] getCipherText(byte[] bytes) {
return Arrays.copyOfRange(bytes, 16, bytes.length);
}
然后
public static void main(String[] args) {
System.out.println(decrypt("wVroKV1UnL2NXiImS83hLKpLLJKk"));
System.out.println(decrypt("Q0tWAMZDhqMo0LbtEY7lF9D8Dkor"));
}
这两者都会产生相同的输出——“goody”
最佳答案
There can be multiple IV + Cipher text combinations that can result in my original message. Isn't that a problem?
您使用不同 IV 的原因是您可以使用相同的 key 以不同的密文发送相同的消息两次。
如果它生成相同的密文,对手就会知道发送了相同的消息,从而泄漏有关该消息的信息。因此,IV 的想法是,它生成不同的密文,并且在大多数情况下,这是有益的而不是问题。
是否有问题取决于您的协议(protocol)。请注意,密文长度仍然可能显示有关明文的信息(即“肯定,中士”当然会与“否”的加密不同)。
您需要一个身份验证标记/MAC 值来防止消息发生更改。此外,您可能需要包含消息序列号之类的内容,以确保不会发生重放攻击。
但是,越深入,加密就会变得越复杂。如果您需要安全传输,那么最终使用 TLS 或 SSH(或任何其他适用的传输层安全性)会变得更加容易。
Also, is it safe to send IV as such (i.e. prepend/append to the cipher text) or there is some procedure that I should follow?
前置它(“前置”在许多词典中不是一个词,你也可以使用“前缀”)是处理 IV 的常见方法,是的。 IV 无论如何都可以发送,并且不需要保密。然而,对于 CBC,它必须是随机的,而不是序列号。
关于java - 发送带有密文的 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48045751/