到目前为止,我发现的很多项目都有点模糊或......非特定,所以我希望得到答案。
我有两个小方法 - 容易看起来像......
private const string initVector = "1234567890123456";
private const string SaltValue = "ThisIsMySaltValue";
private const int KeySize = 256;
public static string Encrypt(string textToEncrypt)
{
var rijndael = new RijndaelManaged {KeySize = KeySize};
var salt = SaltValue.ToByteArray();
var vector = initVector.ToByteArray();
var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
var key = rfcBytes.GetBytes(rijndael.KeySize/8);
ICryptoTransform encrypt = rijndael.CreateEncryptor(key, vector);
var stream = new MemoryStream();
var data = Encoding.ASCII.GetBytes(textToEncrypt);
stream.Write(data, 0, data.Length);
var cryptoStream = new CryptoStream(stream, encrypt, CryptoStreamMode.Write);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
cryptoStream.Close();
return Convert.ToBase64String(stream.ToArray());
}
public static string Decrypt(string textToDecrypt)
{
var vector = initVector.ToByteArray();
var salt = SaltValue.ToByteArray();
var encrypted = textToDecrypt.ToByteArray();
var rijndael = new RijndaelManaged {KeySize = KeySize};
var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
var key = rfcBytes.GetBytes(rijndael.KeySize/8);
var decrypt = rijndael.CreateDecryptor(key, vector);
var stream = new MemoryStream(encrypted);
var cryptoStream = new CryptoStream(stream, decrypt, CryptoStreamMode.Read);
byte[] plainBytes = new byte[textToDecrypt.Length];
var decryptedLength = cryptoStream.Read(plainBytes, 0, plainBytes.Length);
var plainText = Encoding.UTF8.GetString(plainBytes, 0, decryptedLength);
return plainText;
}
单元测试看起来像这样......
[Test]
public void JustTestingThisOut()
{
var encryptMe = "SomethingToEncrypt";
string result = encryptMe.ConvertToEncrypted();
result.ShouldNotEqual(encryptMe);
string backToReadAble = result.ConvertToDecrpted();
backToReadAble.ShouldEqual(encryptMe);
}
ToByteArray只返回Encoding.UTF8.GetBytes(toByte);我的测试字符串很简单 - “SomethingToEncrypt”。我找到this认为可能是问题(Convert.ToBase64String和Convert.FromBase64String)似乎没有任何区别的兔子洞。至于错误...
测试用例 'Tests.Encryption.EncryptionUnitTests.JustTestingThisOut' 失败: System.Security.Cryptography.CryptographicException :要解密的数据的长度是 无效。在 System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(字节[] inputBuffer,Int32 inputOffset,Int32 inputCount)
我有FlushFinalBlock(),我认为这样做,但是......不,也没有区别。有任何想法吗?要尝试的事情?
答案 0 :(得分:0)
加密时,首先将data
写入stream
,然后用stream
包裹CryptoStream
并再次写data
,这次加密。为什么?解密失败是因为遇到的第一件事是未加密的数据。
在 base64编码之前打印密文的值以验证这一点。你应该看到明文后面跟着一堆gobbledygook作为密文。
此外,您使用初始化向量作为密码。它们绝对不是一回事,像这样使用会损害安全性。
答案 1 :(得分:0)
我无法看到这将如何起作用,因为在你执行的解密功能中
var encrypted = textToDecrypt.ToByteArray();
这里textToDecrypt是一个base64字符串。首先必须将base64转换回普通字节,然后可以使用它来解密。
答案 2 :(得分:0)
您的代码中潜伏着间歇性的错误......
您绝不应将任何System.Text.Encoding类用于密文。您将遇到间歇性错误。您应该使用Base64编码和System.Convert类方法。
Convert.ToBase64String(byte[] bytes)
Convert.FromBase64String(string data)
另外需要注意的是,在进行加密时您需要FlushFinalBlock()
,否则无法正确填充。
有关其他信息,请参阅MS安全大师Shawn Fanning的帖子http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx