良好的AES初始化向量惯例

根据我的问题,Aes Encryption

…缺少重要的内容,我现在了解到我对在字符串上创建可逆加密的假设有点过头。我现在有

    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进行硬编码或从键派生它。我想知道这是否是一个好习惯,或者是否会使加密的值容易受到攻击……或者我是否真的对此深思熟虑,应该对IV进行硬编码?

根据Iridium的建议,我尝试了以下方法:

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

{

byte[] buffer;

ms.Read(buffer, 0, 16);

provider.IV = buffer;

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

}

}

}

}

}

但是,这在我的单元测试中显示出一些奇怪的地方:

    [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。有很多类似的东西,但这是我的加密。”这 似乎

几乎是正确的,但当然是完全错误的。看起来好像我已经接近了。我是否在内存流上缺少偏移量?

回答:

对于您的加密方法的每次运行,IV应当是随机的且唯一的。从密钥/消息派生它或对其进行硬编码是不够安全的。IV可以在此方法中生成,而不是传递给它,并在加密数据之前写入输出流。

解密时,可以在加密数据之前从输入中读取IV。

以上是 良好的AES初始化向量惯例 的全部内容, 来源链接: utcz.com/qa/417092.html

回到顶部