How to obtain different cipher text for same plain text using AES

为君一笑 提交于 2019-12-04 04:33:57

问题


I am currently using AesManaged class in C# to encrypt a plain text. It works fine.

However, it produces the same cipher text each time it encrypts same piece of data. Is there anyway I can tweak this behavior and produce different cipher text for same piece of data?

I have implemented encryption in SQL server using AES_256 algorithm and certificate. The process closely resembles with the post here: http://www.codeproject.com/Articles/662187/FIPS-Encryption-Algorithms-and-Implementation-of-A. In this process each time a plain text is encrypted, different cipher text is produced.

I want the same effect with C# code. How that can be achieved?

EDIT: Here is how I implemented the approach suggested by Yolanda Ruiz:

Encrypt

public static string Encrypt(string plainText)
    {
        //Check for valid arguments.
        if (String.IsNullOrEmpty(plainText)) throw new ArgumentNullException("plainText");

        List<byte> encryptedList;

        //Create Aes object
        using (AesManaged aes = new AesManaged())
        {
            aes.Key = Key;
            aes.GenerateIV();
            encryptedList = aes.IV.ToList();
            aes.BlockSize = BlockSize;

            /*Here goes the standard code to encrypt the plain text - refer msdn for that*/
            /*Append the encrypted stream to encryptedList*/
        }

        return encryptedList.ToArray().ToBase64();
    }

Decrypt

        public static string Decrypt(string cipherText)
    {
        //Check for valid arguments.
        if (string.IsNullOrEmpty(cipherText)) throw new ArgumentNullException("cipherText");

        string plainText;
        byte[] cipherTextArray = cipherText.FromBase64();

        //Create Aes object
        using (AesManaged aes = new AesManaged())
        {
            aes.Key = Key;
            aes.BlockSize = BlockSize;
            aes.IV = cipherTextArray.Take(NoOfBytes).ToArray();//Extract the IV
            cipherTextArray = cipherTextArray.Skip(NoOfBytes).ToArray();//Extract the actual plain text.

            /*Here goes the standard code to Decrypt the cipher text - refer msdn for that*/
            /*Assign the decrypted stream output to plainText*/
        }
        return plainText;
    }

Unit Test

        //Arrange
        string plainText = "Sayan";

        //Act
        string cipherText1 = MyCrypto.Encrypt(plainText);
        string cipherText2 = Crypto.Encrypt(plainText);
        string plainText1 = Crypto.Decrypt(cipherText1);
        string plainText2 = Crypto.Decrypt(cipherText2);

        //Assert
        //Check the cipher text is different everytime
        Assert.AreNotEqual(cipherText1, cipherText2);

        //Check that every plaintext output should match with the original
        Assert.AreEqual(plainText, plainText1);
        Assert.AreEqual(plainText, plainText2);

回答1:


The way to do that is to use a different Initialization Vector for each encryption.

The default mode of operation in AesManaged is CBC. In this mode, when a block of plaintext is encrypted, it is first mixed with the result of the encryption of the previous block. As long as the previous ciphertext block is always different, this prevents two similar blocks of plaintext to output the same ciphertext. But what do we use for the very first block then? The initialization vector.

The IV is basically a randomized block that acts as if it was the result of encrypting an hypothetical plaintext block coming before the actual first block of plaintext.

The IV has to be kept around so we can feed it to the decryption method. As it is semantically a ciphertext block, it is usual to prepend it to the actual ciphertext. When decrypting, you would first extract the first block of ciphertext (as is, without decrypting) and use it as the IV to decrypt subsequent blocks.

The IV is not a secret. The attacker will not be able to derive the key or the first plaintext block from it. You must never reuse the same IV twice with the same key though, or you loose the randomization property.

The methods you will want to look at are AesManaged.GenerateIV(), AesManaged.BlockSize (which is in bits, keep it in mind if you use that property to extract the IV bytes from the ciphertext).




回答2:


Encryption algorithms have to be deterministic (otherwise there's no way of reversing them)

If you want to get different cipher text, you'll have to change the key, or the data to be encrypted (or the actual algorithm).



来源:https://stackoverflow.com/questions/22126412/how-to-obtain-different-cipher-text-for-same-plain-text-using-aes

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