c# - 使用 Rijndael 加密时的 key 、盐和 IV

标签 c# asp.net encryption rijndaelmanaged

我正在开发一个用户可以上传文件的网站。我想加密这些文件,以防在授予它们访问权限时出现某种安全漏洞。

当用户想要下载他们的文件时,我直接解密到 HTTP(S) 输出流。

文件放在光盘上,每个文件的记录都插入到网站数据库中,并带有一些附加数据(文件名、大小、文件路径、IV 等)。

我对如何使用加密只有基本的了解,因此有一些疑问。

我正在使用 Rfc2898DeriveBytes 生成加密 key 的字节。使用这个类可以吗?据我所知,它使用 SHA1,这可能不再安全?

现在我对每次加密都使用相同的密码和盐,但每次都是随机 IV。我是否也应该随机化盐并将其与 IV 一起保存在数据库中?这会提供额外的安全性吗?

我应该使用消息验证码 (MAC) 吗?加密文件本身只是存储,不会传输,所以我不知道是否有必要。

我真的不知道如何最好地存储加密密码。我不想将它包含在我的网站 DLL 中,所以我可能会将它放在服务器上某个不在我的网站文件夹中的文件中。我还能怎么做?

这是我的加密代码。是否存在明显的安全漏洞?

const int bufferSize = 1024 * 128;

Guid guid = Guid.NewGuid();
string encryptedFilePath = Path.Combine(FILE_PATH, guid.ToString());
byte[] rgbIV;

using (Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes("PASSWORD HERE", Encoding.ASCII.GetBytes("SALT HERE")))
{
    byte[] rgbKey = deriveBytes.GetBytes(256 / 8);

    using (FileStream decryptedFileStream = File.OpenRead(decryptedFilePath))
    using (FileStream encryptedFileStream = File.OpenWrite(encryptedFilePath))
    using (RijndaelManaged algorithm = new RijndaelManaged() { KeySize = 256, BlockSize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.ISO10126 })
    {
        algorithm.GenerateIV();
        rgbIV = algorithm.IV;

        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(rgbKey, rgbIV))
        using (CryptoStream cryptoStream = new CryptoStream(encryptedFileStream, encryptor, CryptoStreamMode.Write))
        {
            int read;
            byte[] buffer = new byte[bufferSize];
            while ((read = decryptedFileStream.Read(buffer, 0, bufferSize)) > 0)
                cryptoStream.Write(buffer, 0, read);
            cryptoStream.FlushFinalBlock();
        }
    }
}

最佳答案

I'm using Rfc2898DeriveBytes to generate the bytes for the encryption key. Is it okay to use this class? As far as I know it uses SHA1, which might no longer be secure?

最近 SHA-1 的有效破坏实际上只影响了 PBKDF2(Rfc2898DeriveBytes 背后的算法)不需要的抗碰撞性。请参阅:Is PBKDF2-HMAC-SHA1 really broken?

Right now I'm using the same password and salt for each encryption, but a random IV each time. Should I also be randomizing the salt and keep it in the database along with the IV? Will this give additional security?

也许它会提供额外的安全性,但这样做肯定不会有什么坏处,除非你添加了一个错误。来源:Need for salt with IV

Should I be using a message authentication code (MAC)? The encrypted files themselves are only stored and never transferred, so I don't know if it's necessary.

通常,存储系统有检查和程序来防止和修复数据损坏。如果您没有,那么 MAC 是检查数据是否损坏的好方法,即使这不是恶意发生的。

如果最终用户应该接收数据,他们可以自己检查 MAC 并确保没有人更改密文。

I don't really know how to best store the encryption password. I don't want to include it in my website DLL, so I'll probably have it in a file on the server somewhere that isn't in my website folder. How else could I be doing this?

据我了解,您实际上想要持有加密/解密 key 。您可以做的任何事情实际上都是混淆视听,并不能提供任何实际的安全性。攻击者可能只是使用与您常用代码相同的数据存储连接。充其量,攻击者的速度会慢一点。最糟糕的是,他们甚至没有注意到数据已加密,因为解密是透明进行的。

最好确保攻击者无法进入。查看 OWASP 前 10 名并尝试遵循建议。然后您可以使用 Nikto 进行一些安全扫描或聘请专业的渗透测试人员。

This is my code for encryption. Any obvious security flaws?

使用 PaddingMode.ISO10126 似乎不是一个好主意。您应该使用 PKCS#7 填充。来源:Why was ISO10126 Padding Withdrawn?

关于c# - 使用 Rijndael 加密时的 key 、盐和 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42752219/

相关文章:

java - 从密码生成 key 对

c - 使用 RSA 算法加密-字母 'w' ,'x' ,'y' ,'z'

c# - 使用 LINQ 从值的哈希集中检查父项的后代

c# - 无法使用带有 Visual Studio 2015 的 IIS Express 调试 ASP.NET 5

asp.net - asp.net 菜单悬停背景颜色无法更改

asp.net - 在gridview中自动生成序列号

c# - .NET Entity Framework Core 2.0 - 代码优先 - 意外的表关系结果

c# - 发送参数后异步等待事件

javascript - 调用 RegisterStartupScript 时出现 "Object expected"错误

c++ - 如何使用 C++ 加密文件夹?