[英]I am using GUID as key and it's throwing error Specified key is not a valid size for this algorithm
I have below method for symmetric encryption a string content,我有以下对称加密字符串内容的方法,
public static class EncodeExtension
{
public static string AesEncryptString(this string plainText, string key)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
}
Now I want to pass a random Guid
as a key for each string content string,现在我想传递一个随机
Guid
作为每个字符串内容字符串的键,
var key1 = Guid.NewGuid().ToString();
var encryptedData = "test1".AesEncryptString(key1);
var key2 = Guid.NewGuid().ToString();
var encryptedData = "test2".AesEncryptString(key2);
Here I am getting Specified key is not a valid size for this algorithm
?在这里我得到
Specified key is not a valid size for this algorithm
? What key size it's expecting here?这里期望的密钥大小是多少? I do generate a random key size?
我会生成随机密钥大小吗?
Even if you can, never use a GUID for encryption key because they're not produced with a cryptographically secure random generator (CSRNG), so it's way easier to crack a GUID-based key than a securely generated key.即使可以,也不要使用 GUID 作为加密密钥,因为它们不是使用加密安全随机生成器 (CSRNG) 生成的,因此破解基于 GUID 的密钥比安全生成的密钥更容易。 Never use GUID for cryptographically sensitive operations.
切勿将 GUID 用于加密敏感操作。
I don't even recommend running a KDF over the GUID as that doesn't change the low entropy underneath.我什至不建议在 GUID 上运行 KDF,因为这不会改变下面的低熵。
As of .NET 6, it's way easier to generate a cryptographically secure random key:从 .NET 6 开始,生成加密安全随机密钥要容易得多:
byte[] key = RandomNumberGenerator.GetBytes(32); // generate 256-bits
byte[] iv = new byte[16];
byte[] array;
using var aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
Everything about this is terribly broken.这一切都被严重破坏了。
16 bytes that represent a valid UTF8 string, is not very random.代表有效 UTF8 字符串的 16 个字节不是很随机。 If I saw your code, I would be able to guess a significant fraction of the bits of your key.
如果我看到您的代码,我将能够猜出您密钥的很大一部分。
.IV
must always be unique. .IV
必须始终是唯一的。 If you ever encrypt two different inputs with the same .Key
& .IV
, your encryption can be easily broken.如果您曾经使用相同的
.Key
和.IV
加密两个不同的输入,那么您的加密很容易被破解。 It's common to generate a random IV and write it as plain text into the output.生成随机 IV 并将其作为纯文本写入 output 是很常见的。 eg
memoryStream.Write(aes.IV)
例如
memoryStream.Write(aes.IV)
Using a salted hash to turn a password string into a key is better, but only if you can ensure that your salt is kept secret.使用加盐的 hash将密码字符串转换为密钥会更好,但前提是您可以确保您的盐是保密的。
This error comes from the fact that the size in bytes of the GUID UTF8 string isn't a valid key size for AES (128, 192 or 256 bits).此错误源于 GUID UTF8 字符串的字节大小不是 AES 的有效密钥大小(128、192 或 256 位)。
You could use a key derivation function such as PBKDF2 to derive the key from your GUID.您可以使用密钥派生 function (例如PBKDF2 )从您的 GUID 派生密钥。 PBKDF2 is implemented in .net by the class Rfc2898DeriveBytes
PBKDF2由 class Rfc2898DeriveBytes在 .net 中实现
public static string AesEncryptString(this string plainText, string key) {
byte[] array;
byte[] keyBytes;
using (Aes aes = Aes.Create())
{
using (Rfc2898DeriveBytes pbkdf = new Rfc2898DeriveBytes(key, Encoding.UTF8.GetBytes(key)))
{
// here 16 bytes for AES128
keyBytes = pbkdf.GetBytes(16);
}
aes.Key = keyBytes;
//for convenience here we use the key as iv too
aes.IV = keyBytes;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
Be careful as you will have to use the same behavior to generate the key on decryption too.请小心,因为您也必须使用相同的行为来生成解密密钥。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.