Java 是什么让使用Base64的AES为相同的纯文本生成不同的加密结果?
这是一个名为test()的示例伪代码,我运行了10万次,得到了相同纯文本的不同加密消息(显然,我得到的解密是原始纯文本) 我想这背后的原因是为了避免频率;但是为什么一次解密可以有多个加密呢?这不是一对一吗Java 是什么让使用Base64的AES为相同的纯文本生成不同的加密结果?,java,encryption,base64,aes,Java,Encryption,Base64,Aes,这是一个名为test()的示例伪代码,我运行了10万次,得到了相同纯文本的不同加密消息(显然,我得到的解密是原始纯文本) 我想这背后的原因是为了避免频率;但是为什么一次解密可以有多个加密呢?这不是一对一吗 public static void test() { String plainMessage = "I'm gonna bid 100 USD on this project"; String password = "A99922000001000004581F0F0CCD0
public static void test()
{
String plainMessage = "I'm gonna bid 100 USD on this project";
String password = "A99922000001000004581F0F0CCD0000";
Set<String> set = new HashSet<String>();
for (int x=0; x<100000; x++)
{
String enc = AESEncryption.encryptMessage(plainMessage, password);
System.out.println(enc);
set.add(enc);
String dec = AESEncryption.decryptMessage(enc, password);
if (!dec.equals(plainMessage))
{
System.out.println("wrong decryption"); //never gets here
break;
}
}
System.out.println(">"+set.size()); //just to make sure they are all unique
}
为使评论更加清晰: iv或初始化向量类似于第二个密钥,用于加密数据 由于您每次都使用随机iv(这很好),因此每次都会得到不同的加密文本。第二个密钥实际上包含在加密文本中,所以不需要单独传递
只有iv不能使您破解加密(这就是为什么您可以将其与加密文本一起传递的原因),但是通过使用它,您可以使用相同的密码多次发送相同的纯文本(使用不同的iv)并获得完全不同的加密值,因为您使用的是随机IVA,您认为这会起什么作用:
rnd.nextBytes(ivData)代码>?我将添加一个IV是一个初始化向量,目的是尝试并防止针对密码系统的已知文本攻击。我可以用Javascript转换它吗?明白了,有意义。感谢不要使用术语“密钥”来描述IV。第二个加密/解密参数可以,但不是第二个密钥。@OlegEstekhin-具体原因是什么?@jtahlborn仅用于测试目的,如果我想使用上述代码生成类似的加密字符串,该怎么办。怎么做
public static String encryptMessage(final String plainMessage, final String symKeyHex)
{
final byte[] symKeyData = DatatypeConverter.parseHexBinary(symKeyHex);
final byte[] encodedMessage = plainMessage.getBytes(Charset.forName("UTF-8"));
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final int blockSize = cipher.getBlockSize();
// create the key
final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
// generate random IV using block size (possibly create a method for
// this)
final byte[] ivData = new byte[blockSize];
final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
rnd.nextBytes(ivData);
final IvParameterSpec iv = new IvParameterSpec(ivData);
cipher.init(Cipher.ENCRYPT_MODE, symKey, iv);
final byte[] encryptedMessage = cipher.doFinal(encodedMessage);
// concatenate IV and encrypted message
final byte[] ivAndEncryptedMessage = new byte[ivData.length + encryptedMessage.length];
System.arraycopy(ivData, 0, ivAndEncryptedMessage, 0, blockSize);
System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage, blockSize, encryptedMessage.length);
final String ivAndEncryptedMessageBase64 = DatatypeConverter.printBase64Binary(ivAndEncryptedMessage);
return ivAndEncryptedMessageBase64;
}catch (InvalidKeyException e)
{
throw new IllegalArgumentException("key argument does not contain a valid AES key");
}catch (GeneralSecurityException e)
{
throw new IllegalStateException("Unexpected exception during encryption", e);
}
}