我使用常规密钥加密我的消息,并使用Java中的AES/CTR/NoPadding
随机IV。
我计划将IV添加到密文,然后Base64
对其进行编码。
现在,有一个问题困扰着我。可以有多个IV
+ Cipher文本组合,可以生成我的原始邮件。这不是问题吗?另外,这样发送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"));
}
这两个产生相同的输出 - “好”
答案 0 :(得分:2)
可能有多个IV + Cipher文本组合可能会导致我的原始邮件。这不是问题吗?
您使用不同IV的原因是您可以使用相同的密钥使用不同的密文两次发送相同的消息。
如果它会生成相同的密文,则对手会知道发送了相同的消息,泄露了有关该消息的信息。所以IV 的想法是它产生了一个不同的密文,在大多数情况下这是有益的而不是问题。
如果是问题取决于您的协议。请注意,密文长度仍然可以显示有关明文的信息(即"肯定,警长和#34;当然会与#34; No"的加密不同。)
您需要一个身份验证标记/ MAC值来防止更改邮件。此外,您可能希望包含一些消息序列号,以确保重放攻击不会发生。
但是,越深入,加密变得越复杂。如果您需要安全传输,那么最终使用TLS或SSH(或任何其他适用的传输层安全性)会更容易。
另外,这样发送IV是否安全(即在密文前加/附加)或者我应该遵循一些程序?
前置它(" prepend"在许多词典中不是一个词,你可以使用"前缀"以及)是处理IV的常用方法,是的。无论如何都可以发送IV并且它不需要保密。在CBC的情况下,它必须是随机的,而不是序列号。