什么使AES与Base64生成不同的加密结果相同的纯文本? [英] What makes AES with Base64 generate different encryption result for the same plain text?

查看:180
本文介绍了什么使AES与Base64生成不同的加密结果相同的纯文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个名为test()的虚拟代码示例,我运行这个100K次,并且为相同的纯文本得到不同的加密消息(显然,我得到的解密是原始的纯文本)。

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
}

加密

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


推荐答案

添加一些清晰的评论:

iv 向量用于加密数据的第二个密钥

由于您使用随机的 / em>每次(这是好的),你每次都得到不同的加密文本。这个第二个实际上包含在加密文本中,因此您不需要单独传递。

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.

刚刚使用 iv 不能使您破解加密(这就是为什么可以传递以及加密文本),但通过使用它,您可以使用相同的密码多次发送相同的纯文本(使用不同的 ivs ),并获得完全不同的加密值

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.

这篇关于什么使AES与Base64生成不同的加密结果相同的纯文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆