对称加密 (AES):将 IV 和 Salt 与加密数据一起保存是

Symmetric Encryption (AES): Is saving the IV and Salt alongside the encrypted data safe and proper?(对称加密 (AES):将 IV 和 Salt 与加密数据一起保存是否安全且正确?)
本文介绍了对称加密 (AES):将 IV 和 Salt 与加密数据一起保存是否安全且正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I am trying to make sense of how to handle and manage an initilization vector and salt (when applicable) when encrypting and decrypting data using a symmetric encryption algorithm, in this case AES.

I have deduced from different SO threads and various other websites that neither the IV or salt need to be secret, only unique in order to defend against cryptanalytic attacks such as a brute-force attack. With this in mind I figured that it would be viable to store my pseudo random IV with the encrypted data. I am asking if the method I am using is proper and furthermore, should I be treating my currently hard coded salt in the same manner? That being writing it to the memory stream along side the IV

My code:

private const ushort ITERATIONS = 300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22,  0x3c };

private static byte[] CreateKey(string password, int keySize)
{
    DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
    return derivedKey.GetBytes(keySize >> 3);
}

public static byte[] Encrypt(byte[] data, string password)
{
    byte[] encryptedData = null;
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.GenerateIV();
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;

        using (MemoryStream memStream = new MemoryStream(data.Length))
        {
            memStream.Write(provider.IV, 0, 16);
            using (ICryptoTransform encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                }
            }
            encryptedData = memStream.ToArray();
        }
    }
    return encryptedData;
}

public static byte[] Decrypt(byte[] data, string password)
{
    byte[] decryptedData = new byte[data.Length];
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;
        using (MemoryStream memStream = new MemoryStream(data))
        {
            byte[] iv = new byte[16];
            memStream.Read(iv, 0, 16);
            using (ICryptoTransform decryptor = provider.CreateDecryptor(provider.Key, iv))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                {
                    cryptoStream.Read(decryptedData, 0, decryptedData.Length);
                }
            }
        }
    }
    return decryptedData;
}

I am also open to any other information about symmetric encryption with regards to proper practice.

解决方案

Storing the IV and Salt along with the cipher text is proper and a best practice. Hard coding the salt is not useful, being random is important, hard coding the iterations is perfectly okay but is typically much higher than 300 (in fact at least 1000 and you typically go much higher if your machine/usage can handle it as in 10s of thousands).

Because I've seen so many bad (or old) examples of c# encryption from stack overflow cut and paste into open source code, I wrote a short bit of cut and paste encryption code Modern Examples of Symmetric Authenticated Encryption of a string. that i try to keep up to date and reviewed. It stores the iv and salt with the ciphertext it also authenticates the ciphertext and values included with the cipher text.

Ideally though a better practice would be to use a high level encryption library that would handle best practices like the iv for you, however those typically haven't existed for csharp. I've been working on a native csharp version of google's keyczar library. While it's functionally ready for use, I've been wanting to get more eyes on the code before the first official stable release.

这篇关于对称加密 (AES):将 IV 和 Salt 与加密数据一起保存是否安全且正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)