我有一个AES Cryptography包装器和单元测试,已经工作了一年多。现在安装VS 2012(或者可能是对.net Framework 4的更新)后,单元测试没有通过。当我传入一个错误的传递但没有抛出ArgumentNullException时,streamreader块抛出了CryptographicException。
代码到了。 https://github.com/jnaus/Cryptography
这是现在不起作用的单元测试。 (BadSaltTest有同样的问题)
[TestMethod]
[ExpectedException(typeof(CryptographicException),
"Bad password was inappropriately allowed")]
public void BadPasswordTest()
{
var cipherText = EncryptString();
var decryptedText = AESCryptography.DecryptStringAES
(cipherText,"A bad password", salt);
}
测试结果: 测试方法CryptographyTest.AESTest.BadPasswordTest引发异常System.ArgumentNullException,但预期会出现异常System.Security.Cryptography.CryptographicException。异常消息:System.ArgumentNullException:值不能为null。 参数名称:inputBuffer
解密代码。
public static string DecryptStringAES(string cipherText,
string password, byte[] salt)
{
RijndaelManaged aesAlg = null;
string plaintext = null;
try
{
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt);
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize/8);
aesAlg.IV = key.GetBytes(aesAlg.BlockSize/8);
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key,
aesAlg.IV);
// Create the streams used for decryption.
byte[] bytes = Convert.FromBase64String(cipherText);
using (MemoryStream msDecrypt = new MemoryStream(bytes))
{
using (CryptoStream csDecrypt =
new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
//StreamReader now gives ArgumentNullException
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
{
aesAlg.Clear();
}
}
return plaintext;
}
答案 0 :(得分:2)
在搜索了一下之后,这确实看起来确实是微软所诟病的一个错误(见Microsoft Connect)。个人不是建议的解决方法的忠实粉丝,因为它确实不应该需要,但它会在我想的同时做。
答案 1 :(得分:1)
您上面发布的代码为我工作(我必须编写一些代码来创建要传递的加密字符串)。使用.Net Framework 4在VS2012中编译并运行。
我使用的加密代码是:
private static string EncryptStringAES(string plainText, string password, byte[] salt)
{
RijndaelManaged aesAlg = null;
string cypherText = null;
try
{
// generate the key from the shared secret and the salt
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt);
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
byte[] bytes = new UTF8Encoding().GetBytes(plainText);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(bytes, 0, bytes.Length);
csEncrypt.FlushFinalBlock();
cypherText = Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
{
aesAlg.Clear();
}
}
return cypherText;
}
使用以下方法进行方法调用:
byte[] salt = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
string test = DecryptStringAES(EncryptStringAES("This is a test", "Test", salt), "Test", salt);
结果字符串(测试)包含“这是一个测试”。