对称加密(AES):将IV和Salt与加密数据一起保存是否安全吗? [英] Symmetric Encryption (AES): Is saving the IV and Salt alongside the encrypted data safe and proper?

查看:1549
本文介绍了对称加密(AES):将IV和Salt与加密数据一起保存是否安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何使用对称加密算法(在这种情况下为AES)加密和解密数据时,如何处理和管理初始化向量和盐(如果适用)。



我从不同的SO线程和各种其他网站推断,无论是IV还是盐都不是秘密的,只有唯一的,以防御密码分析攻击,如暴力攻击。考虑到这一点,我认为存储我的伪随机IV与加密的数据是可行的。我问,如果我使用的方法是正确的,此外,我应该以相同的方式治疗我目前硬编码盐?正在将它写入IV边的记忆流



我的代码:

  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;
提供者.Padding = PaddingMode.PKCS7;

使用(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 [] decryptptedData = 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(decryptptedData,0,decryptptedData.Length);
}
}
}
}
return decryptedData;
}

我也对任何其他有关对称加密的信息。

解决方案

使用密文存储IV和Salt很长时间是一个最佳实践。硬编码盐是没有用的,随机是重要的,硬编码迭代是完全正确的,但通常远远高于300(事实上至少1000和你通常会高得多,如果你的机器/使用可以处理它在10秒因为我看到这么多坏(或旧的)c#加密的例子从堆栈溢出剪切和粘贴到开源代码,我写了一个短位的剪切和粘贴加密代码对称认证加密的字符串的现代示例,我试图保持最新和审查。它存储iv和salt与密文,它还认证密文和包含在密文中的值。



理想情况下,更好的做法是使用高级加密库将处理像iv的最佳实践,但是那些通常不存在为csharp。我一直在使用本地 csharp版本的Google keyczar library。虽然它的功能已准备好使用,我一直想要在第一次正式稳定版本之前更多地了解代码。


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 a long 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与加密数据一起保存是否安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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