如何使用密码短语生成Rijndael KEY和IV?
如何使用密码短语生成Rijndael KEY和IV? 密钥长度必须为256位。
这是我在互联网上找到的即插即用代码。 它只是工作:
using System.IO; using System.Security.Cryptography; private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c }; public static byte[] Encrypt(byte[] plain, string password) { MemoryStream memoryStream; CryptoStream cryptoStream; Rijndael rijndael = Rijndael.Create(); Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); rijndael.Key = pdb.GetBytes(32); rijndael.IV = pdb.GetBytes(16); memoryStream = new MemoryStream(); cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(plain, 0, plain.Length); cryptoStream.Close(); return memoryStream.ToArray(); } public static byte[] Decrypt(byte[] cipher, string password) { MemoryStream memoryStream; CryptoStream cryptoStream; Rijndael rijndael = Rijndael.Create(); Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); rijndael.Key = pdb.GetBytes(32); rijndael.IV = pdb.GetBytes(16); memoryStream = new MemoryStream(); cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write); cryptoStream.Write(cipher, 0, cipher.Length); cryptoStream.Close(); return memoryStream.ToArray(); }
我认为您正在寻找基于密码的密钥派生。 有Rfc2898DeriveBytes
类来实现它。
Rfc2898DeriveBytes
获取密码,salt和迭代计数,然后通过调用GetBytes
方法生成密钥。
RFC 2898包括用于从密码和盐创建密钥和初始化向量(IV)的方法。 您可以使用基于密码的密钥派生函数PBKDF2,使用伪随机函数导出密钥,该函数允许生成几乎无限长度的密钥。 Rfc2898DeriveBytes类可用于从基本密钥和其他参数生成派生密钥。 在基于密码的密钥派生函数中,基本密钥是密码,其他参数是salt值和迭代计数。
有关PBKDF2的更多信息,请参阅RFC 2898,“PKCS#5:基于密码的加密规范版本2.0”。
例:
public static byte[] CreateKey(string password) { var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 }; const int Iterations = 9872; using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations)) return rfc2898DeriveBytes.GetBytes(32); }
您可以在任何对称算法中使用DeriveBytes
,而不仅仅是Rijndael
。
例:
public static SymmetricAlgorithm InitSymmetric(SymmetricAlgorithm algorithm, string password, int keyBitLength) { var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 }; const int Iterations = 234; using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations)) { if (!algorithm.ValidKeySize(keyBitLength)) throw new InvalidOperationException("Invalid size key"); algorithm.Key = rfc2898DeriveBytes.GetBytes(keyBitLength / 8); algorithm.IV = rfc2898DeriveBytes.GetBytes(algorithm.BlockSize / 8); return algorithm; } } private static byte[] Transform(byte[] bytes, Func selectCryptoTransform) { using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, selectCryptoTransform(), CryptoStreamMode.Write)) cryptoStream.Write(bytes, 0, bytes.Length); return memoryStream.ToArray(); } }
用法:
public static void Main() { using (var rijndael = InitSymmetric(Rijndael.Create(), "TestPassword", 256)) { var text = "Some text to encrypt"; var bytes = Encoding.UTF8.GetBytes(text); var encryptedBytes = Transform(bytes, rijndael.CreateEncryptor); var decryptedBytes = Transform(encryptedBytes, rijndael.CreateDecryptor); var decryptedText = Encoding.UTF8.GetString(decryptedBytes); Debug.Assert(text == decryptedText); } }
确保更改salt
和iterations
参数。
IV必须是随机的(不需要是一个不可预测的随机,只是随机的,它们不会被重用)。
至于从密码生成密钥,你正在寻找一个密钥派生函数 ,现在至少有三个不错的选择(PBKDF2,bcrypt,scrypt),使用非迭代哈希,因为之前的海报建议更多的是不安全的系统。
也使用AES或Rijndael,这不完全相同。 使用Rijndael组合不是AES的一部分可能是后来的互操作性噩梦,并且无论如何这些function组合的安全性都没有得到很好的研究。
IV必须是随机的(您通常将其与加密数据一起传递),并且密钥可以通过多种方式派生:只需将密码填充到密钥的长度(如果密码短于32个字符)或(哪个更可靠)通过使用SHA2散列算法或使用更复杂的方法来导出密钥。
使用此Rfc2898DeriveBytes类 。
建议的话,你的安全级别已经下降/受密码长度/强度的限制。 所以,不要这样做。
上述就是C#学习教程:如何使用密码短语生成Rijndael KEY和IV?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/991623.html