如何使用任何密钥进行加密

How to do encryption with any key

我正在使用 Rijndael 对称算法实现加密。这是可行的,但我想将其更改为可以使用任何键。我不想生成密钥,我想让用户选择自己的密钥,就像他的加密密码一样。

RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.GenerateKey();
myRijndael.GenerateIV();

var encryptor = new RijndaelManagedEncryption();

var encrypted = encryptor.EncryptSettingValue(myRijndael.Key, "Encrypt this", myRijndael.IV);

比如像这样

RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.GenerateIV();
var key = Convert.FromBase64String("pasword")
var encryptor = new RijndaelManagedEncryption();

var encrypted = encryptor.EncryptSettingValue(key , "Encrypt this", myRijndael.IV);

但如果我这样做,我会得到异常:

mscorlib.dll 中发生 'System.FormatException' 类型的未处理异常 附加信息:Base-64 字符数组或字符串的长度无效。

如果你想看算法,这是link:https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx

首先,字符串 "password" 不是一个有效的 Base64 字符串,因此您不能随意转换它。

此外,您不应该仅仅因为它不会生成随机化良好的密钥而从某些字符串中获取用于加密 "straightforward" 的密钥。

使用 Rfc2898DeriveBytes 代替:

var password = "pasword";
var salt = new byte[] { 0xe3, 0x5c, 0x51, 0x6a, 0x13, 0x55, 0x46, 0xf8, 0x75, 0xba, 0x54, 0xc3, 0x42, 0x5b, 0x70, 0xac };
var key = new Rfc2898DeriveBytes(password, salt).GetBytes(32);

这里 salt 是一些随机的字节数组,实际上是什么并不重要。它只需要为密钥生成带来更多随机性并且可以是任意的(但始终相同以确保您从相同的密码生成相同的密钥)。