【发布时间】:2015-03-25 09:22:26
【问题描述】:
我需要加密/解密一些字符串。我已经根据msdn documentation 构建了我的包装类,但做了一些更改。
由于我想使用给定的字符串/密码来加密/解密数据,因此我不使用 AesManaged 来创建密钥。 (用户应该能够使用他输入的密钥进行加密/解密,因此我无法使用来自AesManaged 的密钥,也无法保存密钥)。
我改为使用Rfc2898DeriveBytes (PBKDF2) 和给定的盐来创建密钥。使用给定的盐是因为我不存储密钥,因此我认为盐必须始终相同。
然后我创建一个 IV,加密给定的字符串并将 IV 和加密的字符串连接起来。然后,这最终将保存在一个文件中。这意味着 IV 与加密数据一起保存。
问题:
- 可以将 IV 与加密数据一起存储吗?
- 是否有另一种方法来创建密钥,而无需每次都使用相同的盐(基于给定的密码)?
- 此加密是使用 AES128 还是 AES256 完成的?
- IV 将始终为 16 字节,还是可以更改?
static void Main(string[] args)
{
const string stringToEncrypt = "String to be encrypted/decrypted. Encryption is done via AesManaged";
const string password = "m1Sup3rS3cre!Password";
string encrypted = EncryptString(stringToEncrypt, password);
string roundtrip = DecryptStringFromBytes_Aes(encrypted, password);
Console.WriteLine("Original: {0}", stringToEncrypt);
Console.WriteLine("Round Trip: {0}", roundtrip);
Console.ReadLine();
}
static string EncryptString(string plainText, string password)
{
string encryptedString;
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = PasswordAsByte(password);
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
var encrypted = msEncrypt.ToArray();
encryptedString = Encoding.Default.GetString(aesAlg.IV);
encryptedString += Encoding.Default.GetString(encrypted);
}
}
}
return encryptedString;
}
static string DecryptStringFromBytes_Aes(string cipherText, string password)
{
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = PasswordAsByte(password);
aesAlg.IV = Encoding.Default.GetBytes(cipherText).Take(16).ToArray();
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
var encryptedByteArray = Encoding.Default.GetBytes(cipherText).Skip(16).ToArray();
using (MemoryStream msDecrypt = new MemoryStream(encryptedByteArray))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
}
}
private static byte[] PasswordAsByte(string password)
{
byte[] salt = Encoding.Default.GetBytes("foobar42");
Rfc2898DeriveBytes passwordBytes = new Rfc2898DeriveBytes(password, salt);
return passwordBytes.GetBytes(32);
}
【问题讨论】:
-
很高兴您提供了大部分代码 - 但如果您包含 using 指令和类声明,我们就可以复制、粘贴和编译了。 .
-
这不是 AES 的“实现”,只是您使用 API。
-
我投票结束这个问题,因为这是一个代码审查问题。
-
这是未经身份验证的加密。攻击者可以修改加密数据,而您在解密时无法分辨。你同意吗?
-
关于“AES 的实现”:我刚才说我用 AesManaged 实现了一些东西。也许我的英语不够好。
标签: c# .net encryption aes encryption-symmetric