What makes AES with Base64 generate different encryption result for the same plain text?

 ̄綄美尐妖づ 提交于 2019-12-05 03:55:15

问题


Here's a sample dummy code called test(), I run this 100K times and I get different encrypted messages for the same plain text (obviously, the decryption I get is the original plain text).

I guess the reason behind this is to avoid frequency; but how come there can be MANY encryption to ONE decryption? shouldn't it be a one to one?

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
}

the encryption

    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);
    }
}

回答1:


To add some clarity to the comments:

The iv or initialization vector is like a second key which is used to encrypt the data.

Since you use a random iv each time (this is good), you get different encrypted text each time. This second key is actually included with the encrypted text, so you don't need to pass it along separately.

Having just the iv doesn't enable you to crack the encryption (which is why you can pass it along with the encrypted text), but by using it, you can send the same plain text with the same password multiple times (using different ivs) and get completely different encrypted values.



来源:https://stackoverflow.com/questions/24701068/what-makes-aes-with-base64-generate-different-encryption-result-for-the-same-pla

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!