良好的AES初始化向量实践 [英] Good AES Initialization Vector practice

查看:751
本文介绍了良好的AES初始化向量实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AES加密...缺少一个重要的一块,我现在才知道,我创建一个字符串可逆加密的假设是有点过。我现在有

per my question Aes Encryption... missing an important piece, I have now learned that my assumption for creating a reversible encryption on a string was a bit off. I now have

    public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
    {
        var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                        cs.FlushFinalBlock();
                    }
                    return ms.ToArray();
                }
            }
        }
    }

和这将产生一致的结果;不过,我将无法解密不知道/设置初始化向量。我真的不想三个值传递到这个方法(上为IV),这让我硬编码IV或从密钥导出它。我想知道这是否是一个很好的做法,或者如果它将使该加密值容易受到攻击莫名其妙......还是我得太多真这一点,应该只是硬code中的IV?

and this produces consistent results; however, I will not be able to decrypt without knowing/ setting the initialization vector. I really do not want to pass three values into this method (on for the IV), which leaves me with hardcoding the IV or deriving it from the key. I'd like to know if this is a good practice, or if it will render the encrypted value vulnerable to attack somehow... or am I really overthinking this and should just hardcode the IV?

更新
每铱星的建议,我想这样的事情,而不是:

UPDATE Per Iridium's suggestion, I tried something like this instead:

    public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
    {
        if (string.IsNullOrEmpty(toEncrypt)) throw new ArgumentException("toEncrypt");
        if (encryptionKey == null || encryptionKey.Length == 0) throw new ArgumentException("encryptionKey");
        var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (var ms = new MemoryStream())
                {
                    ms.Write(provider.IV, 0, 16);
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                        cs.FlushFinalBlock();
                    }
                    return ms.ToArray();
                }
            }
        }
    }

    public static string DecryptString(byte[] encryptedString, byte[] encryptionKey)
    {
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var ms = new MemoryStream(encryptedString))
            {
                ms.Read(provider.IV, 0, 16);
                using (var decryptor = provider.CreateDecryptor(provider.Key, provider.IV))
                {
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] decrypted = new byte[encryptedString.Length];
                        var byteCount = cs.Read(decrypted, 0, encryptedString.Length);
                        return Encoding.UTF8.GetString(decrypted, 0, byteCount);
                    }
                }
            }
        }
    }

然而,这表明一些奇怪的在我的单元测试:

however, this shows something odd in my unit test:

    [TestMethod]
    public void EncryptionClosedLoopTest()
    {
        var roundtrip = "This is the data I am encrypting.  There are many like it but this is my encryption.";
        var encrypted = Encryption.EncryptString(roundtrip, encryptionKey);
        var decrypted = Encryption.DecryptString(encrypted, encryptionKey);
        Assert.IsTrue(roundtrip == decrypted);
    }

我的解密文本显示为92ʪF,hpv0我加密。有很多喜欢它,但是这是我的加密。这看起来的差不多了吧,但当然完全错误的。它看起来像我接近,虽然,我错过了在内存流偏移?

my decrypted text shows up as "92ʪ�F"�,hpv0�� I am encrypting. There are many like it but this is my encryption." which seems almost right but of course completely wrong. It looks like I'm close though. Am I missing an offset on the memory stream?

推荐答案

该IV应该是随机的,独特的为您的加密方法的每一次运行。从键/消息或衍生它的硬编码是不够安全。在第四可以此方法中的加密数据之前,要产生,而不是传递到它,并写入到输出流中。

The IV should be random and unique for every run of your encryption method. Deriving it from the key/message or hard-coding it is not sufficiently secure. The IV can be generated within this method, instead of passed into it, and written to the output stream prior to the encrypted data.

解密时,第四然后可以从输入的加密数据之前,读

When decrypting, the IV can then be read from the input before the encrypted data.

这篇关于良好的AES初始化向量实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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