[英]I am using GUID as key and it's throwing error Specified key is not a valid size for this algorithm
我有以下對稱加密字符串內容的方法,
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);
}
}
現在我想傳遞一個隨機Guid
作為每個字符串內容字符串的鍵,
var key1 = Guid.NewGuid().ToString();
var encryptedData = "test1".AesEncryptString(key1);
var key2 = Guid.NewGuid().ToString();
var encryptedData = "test2".AesEncryptString(key2);
在這里我得到Specified key is not a valid size for this algorithm
? 這里期望的密鑰大小是多少? 我會生成隨機密鑰大小嗎?
即使可以,也不要使用 GUID 作為加密密鑰,因為它們不是使用加密安全隨機生成器 (CSRNG) 生成的,因此破解基於 GUID 的密鑰比安全生成的密鑰更容易。 切勿將 GUID 用於加密敏感操作。
我什至不建議在 GUID 上運行 KDF,因為這不會改變下面的低熵。
從 .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;
這一切都被嚴重破壞了。
代表有效 UTF8 字符串的 16 個字節不是很隨機。 如果我看到您的代碼,我將能夠猜出您密鑰的很大一部分。
.IV
必須始終是唯一的。 如果您曾經使用相同的.Key
和.IV
加密兩個不同的輸入,那么您的加密很容易被破解。 生成隨機 IV 並將其作為純文本寫入 output 是很常見的。 例如memoryStream.Write(aes.IV)
使用加鹽的 hash將密碼字符串轉換為密鑰會更好,但前提是您可以確保您的鹽是保密的。
此錯誤源於 GUID UTF8 字符串的字節大小不是 AES 的有效密鑰大小(128、192 或 256 位)。
您可以使用密鑰派生 function (例如PBKDF2 )從您的 GUID 派生密鑰。 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);
}
請小心,因為您也必須使用相同的行為來生成解密密鑰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.