从早期的问题中继续排序,做了一堆谷歌搜索,但我不认为我在这里正确的道路上。基本上我正在做的是用一段代码打开一个文件,如下所示:
byte[] cipherText = File.ReadAllBytes(encryptedFile);
然后将该字节数组传递给静态bool方法,该方法调用实际的解密方法,如果没有引发加密异常,则返回true。在我的主窗体上,我有一个按钮单击,它从一个If语句调用静态bool,如果它返回true则解锁一些额外的接口项,如果它返回false则弹出一个“无效密码”消息框。
我逐步完成整个过程,并抛出“填充无效,无法删除”。异常,一些搜索显示应该在提供错误的解密密钥时发生。我知道我正在传递相同的密钥,至少我正在键入它,所以我假设问题与byte []的传递方式或者流本身有关。以下是解密方法的示例:
public static string Decrypt(string password, byte[] ciphertext)
{
byte[] key, iv;
CreateKeyIV(password, out key, out iv);
using (MemoryStream encrypted = new MemoryStream(ciphertext))
using (CryptoStream dec = new CryptoStream(encrypted, _algorithm.CreateDecryptor(key, iv), CryptoStreamMode.Read))
using (StreamReader reader = new StreamReader(dec))
{
try
{
return reader.ReadToEnd();
}
catch (CryptographicException)
{
throw new CryptographicException("Invalid password.");
}
finally
{
encrypted.Close();
dec.Close();
reader.Close();
}
}
}
有人看到我缺少的东西吗?
答案 0 :(得分:4)
解密代码看起来没问题,虽然我会做一些改动:
MemoryStream
作为来源时将数据包装在FileStream
中Close
- 这就是使用声明的目的CryptographicException
,而不是让现有的异常冒泡?换句话说,这就是我的方法:
public static string Decrypt(string password, Stream encrypted)
{
byte[] key, iv;
CreateKeyIV(password, out key, out iv);
using (CryptoStream dec = new CryptoStream(encrypted,
_algorithm.CreateDecryptor(key, iv), CryptoStreamMode.Read))
using (StreamReader reader = new StreamReader(dec))
{
return reader.ReadToEnd();
}
}
但是,你已经在另一条评论中表明了错误:
// Bad code! Do not use!
byte[] newCipher = Encryptor.Encrypt(newPass, newPass);
string writeIt = System.Text.Encoding.UTF8.GetString(newCipher);
您正在破坏加密数据。加密结果很少是有效的UTF-8字符串。您应该直接将其写入磁盘 in binary ,而不是尝试将其转换为文本。您的加密代码可以直接执行此操作,也可以调用File.WriteAllBytes()
。如果绝对必须在某个时刻将任意二进制数据转换为字符串,则应使用Convert.ToBase64String(data)
将其转换为base64。这样你以后可以通过再次转换它来获得相同的二进制数据。试图将其“解码”为文本是一种几乎可靠的方式来丢失数据 - 就像你在这里一样。
答案 1 :(得分:0)
我不会在StreamReader
上打开CryptoStream
,但实际上我会直接调用类Read
的方法CryptoStream
,并传递byte[]
}缓冲区,它将保存解密数据。
这是我的一个片段。我已经将它用于MemoryStream和FileStream。
Stream s = ...;
ICryptoTransform cTransform = Encryptor.CreateDecryptor();
using (CryptoStream cStream = new CryptoStream(s, cTransform, CryptoStreamMode.Read)) {
byte[] mCryptoData = new byte[s.Length];
cStream.Read(mCryptoData, 0, mCryptoData.Length);
...