如何获取使用AES相同明文不同密文 [英] How to obtain different cipher text for same plain text using AES

查看:1638
本文介绍了如何获取使用AES相同明文不同密文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前使用C#AesManaged级加密一个纯文本。它工作正常。



然而,它会产生相同的密文每次加密相同数据的时候。反正我有可以调整这一行为,并产生了相同的数据不同的密文?



我一直在使用AES_256算法和证书来实现在SQL服务器加密。该过程后非常类似于此: HTTP: //www.codeproject.com/Articles/662187/FIPS-Encryption-Algorithms-and-Implementation-of-A 。在这个过程中的每一个明文进行加密的时间,不同的密文产生



我想与C#代码相同的效果。 ?如何可以实现



编辑:
这里是我如何实现由Yolanda鲁伊斯建议的方法:



加密

 公共静态字符串加密(字符串明文)
{
//检查有效参数。
如果(String.IsNullOrEmpty(明文))抛出新的ArgumentNullException(明文);

名单,LT;字节> encryptedList;

//使用AES创建对象
(AesManaged AES =新AesManaged())
{
aes.Key =键;
aes.GenerateIV();
encryptedList = aes.IV.ToList();
aes.BlockSize =块大小;

/ *这里所说的标准码加密纯文本 - 参见MSDN为* /
/ *追加加密流encryptedList * /
}

返回encryptedList.ToArray()ToBase64();
}



解密



 公共静态字符串解密(字符串密文)
{
//检查有效参数。
如果(string.IsNullOrEmpty(密文))抛出新的ArgumentNullException(密文);

字符串明文;
字节[] = cipherTextArray cipherText.FromBase64();

//使用AES创建对象
(AesManaged AES =新AesManaged())
{
aes.Key =键;
aes.BlockSize =块大小;
aes.IV = cipherTextArray.Take(NoOfBytes).ToArray(); //提取IV
cipherTextArray = cipherTextArray.Skip(NoOfBytes).ToArray(); //提取实际纯文本。

/ *这里所说的标准码解密密文 - 参见MSDN为* /
/ *解密流输出分配给明文* /
}
返回明文;
}



单元测试



  //安排
字符串明文=萨扬;

//法案
串cipherText1 = MyCrypto.Encrypt(明文);
串cipherText2 = Crypto.Encrypt(明文);
串plainText1 = Crypto.Decrypt(cipherText1);
串plainText2 = Crypto.Decrypt(cipherText2);

//断言
//检查密文是不同的,每次
Assert.AreNotEqual(cipherText1,cipherText2);

//检查每一个明文OUT输出应与原来的
Assert.AreEqual(明文,plainText1);
Assert.AreEqual(明文,plainText2);


解决方案

做到这一点的方法是使用一个不同的< A HREF =htt​​ps://en.wikipedia.org/wiki/Initialization_vector>初始化向量每个加密。



在操作的默认模式AesManaged是 CBC 。在这种模式下,当明文块是加密的,它是第一混合与先前块的加密的结果。只要先前密文块总是不同,这样可以防止明文输出两个相似的块相同的密文。但是,我们使用的第一个块呢?初始化向量。



IV基本上是一个随机分组,充当如果它是加密一个假想的明文块未来结果的的了明文的实际第一嵌段



的IV必须保持周围,所以我们可以将其馈送到解密方法。因为它在语义上是一个密文块中,通常将其预先考虑到实际的密文。解密时,您首先会提取密文的第一个块(的正如的,没有解密),并把它作为IV来解密随后的块。



IV是不是一个秘密。攻击者将不能推导密钥,或从它的第一个明文块。你千万不要使用相同的密钥重用相同的IV虽然两次,或者你失去的随机属性。



您想看看是 AesManaged.GenerateIV() AesManaged方法.BlockSize (这是位牢记,如果你使用该属性来提取密文的第四个字节)。


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 out put should match with the original
        Assert.AreEqual(plainText, plainText1);
        Assert.AreEqual(plainText, plainText2);

解决方案

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).

这篇关于如何获取使用AES相同明文不同密文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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