我正在构建一个可以在c#中加密和解密文件的应用程序。加密看起来像它的工作(我认为它的工作)然而解密给我异常"输入数据不是一个完整的块。"我已经尝试了几乎所有我能在网上找到的东西,所以我想我应该来这里。这是解密代码:
static void decryptAES (/*byte[] buffer,*/string filePath,byte[] key, byte[] IV)
{
Console.WriteLine("1");
using (AesCryptoServiceProvider AES = new AesCryptoServiceProvider())
{
AES.Padding = PaddingMode.PKCS7;
AES.Key = key;
AES.BlockSize = 128;
AES.KeySize = 128;
AES.IV = IV;
using (FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (ICryptoTransform crypt = AES.CreateDecryptor(key, IV))
{
using (CryptoStream crStream = new CryptoStream(fStream, crypt, CryptoStreamMode.Read))
{
using (StreamReader reader = new StreamReader(crStream))
{
//breaks here
string data = reader.ReadToEnd();
File.WriteAllText(filePath, data);
File.Move(filePath, filePath.Replace(".encrypted", ""));
}
}
}
}
}
}
顺便说一句,它在注释//中断了。 感谢。
这是加密功能
static void encryptAES(byte[] filesBytes,string
filePath,AesCryptoServiceProvider aes)
{
using (FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (ICryptoTransform crypt = aes.CreateEncryptor(aes.Key, aes.IV))
{
using (CryptoStream csStream = new CryptoStream(fStream, crypt, CryptoStreamMode.Write))
{
csStream.Write(filesBytes, 0, filesBytes.Length);
}
try { File.Move(filePath, filePath + ".encrypted"); }
catch (UnauthorizedAccessException)
{
}
}
}
}
这是密钥生成:
static AesCryptoServiceProvider generateAES()
{
AesCryptoServiceProvider a = new AesCryptoServiceProvider();
a.Padding = PaddingMode.PKCS7;
a.BlockSize =128;
a.KeySize = 128;
a.GenerateIV();
a.GenerateKey();
return a;
}
以下是我存储IV和AES密钥的方法:
private static void dumpKeys(AesCryptoServiceProvider aes)
{
foreach (byte b in aes.Key)
{
Console.Write(b);
}
Console.WriteLine();
foreach (byte b in aes.IV)
{
Console.Write(b);
}
byte[] encryptedKey = encryptRSA(aes.Key);
byte[] encryptedIV = encryptRSA(aes.IV);
Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Keys");
File.WriteAllBytes(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Keys\0000000000000.Key", encryptedKey);
File.WriteAllBytes(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Keys\1111111111111.IV", encryptedIV);
}
以下是我检索密钥和iv数据的方法:
byte[] AESKey = decrypt(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Keys\0000000000000.Key");
byte[] AESIV = decrypt(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Keys\1111111111111.IV");
static byte[] decrypt(string path)
{
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
RSA.FromXmlString(Properties.Resources.privateKey);
byte[] unencrypted = RSA.Decrypt(File.ReadAllBytes(path), true);
foreach (byte b in unencrypted)
{
Console.Write(b);
}
Console.WriteLine();
return unencrypted;
}
}
顺便说一下,我将公共RSA密钥存储在我的资源文件中,然后使用它来解密密钥。 感谢
答案 0 :(得分:0)
到目前为止,这么好。您是否提取生成的Key
和IV
?我将您的解密功能修改为加密功能......
public static void Main()
{
var f = @"q:\test.txt";
AesCryptoServiceProvider AES = new AesCryptoServiceProvider();
AES.Padding = PaddingMode.PKCS7;
AES.Mode = CipherMode.CBC;
AES.BlockSize = 128;
AES.KeySize = 128;
AES.GenerateKey();
AES.GenerateIV();
var key = AES.Key;
var iv = AES.IV;
encryptAES(AES, f, key, iv);
decryptAES(AES, f + ".encrypted", key, iv);
}
static void encryptAES(SymmetricAlgorithm algo, string filePath, byte[] key, byte[] IV)
{
using (FileStream fin = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (FileStream fout = new FileStream(filePath + ".encrypted", FileMode.OpenOrCreate, FileAccess.Write))
{
using (ICryptoTransform crypt = algo.CreateEncryptor(key, IV))
{
using (CryptoStream crStream = new CryptoStream(fout, crypt, CryptoStreamMode.Write))
{
fin.CopyTo(crStream);
}
}
}
}
}
static void decryptAES(SymmetricAlgorithm algo, string filePath, byte[] key, byte[] IV)
{
using (FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (ICryptoTransform crypt = algo.CreateDecryptor(key, IV))
{
using (CryptoStream crStream = new CryptoStream(fStream, crypt, CryptoStreamMode.Read))
{
using (StreamReader reader = new StreamReader(crStream))
{
string data = reader.ReadToEnd();
File.WriteAllText(filePath.Replace(".encrypted", ".restored"), data);
}
}
}
}
}
答案 1 :(得分:0)
使用您的代码对其进行测试,稍加修改(将FileMode.Open
更改为FileMode.OpenOrCreate
,在File.Delete
之前添加File.Move
并将File.WriteAllText
与File.Move
合并)它的工作原理。所以a)请检查您的代码。 b)如果仍然失败,请提供更多详细信息,包含每个功能的单个代码块以及调用函数重现故障的Main方法......
static AesCryptoServiceProvider generateAES()
{
AesCryptoServiceProvider a = new AesCryptoServiceProvider();
a.Padding = PaddingMode.PKCS7;
a.BlockSize = 128;
a.KeySize = 128;
a.GenerateIV();
a.GenerateKey();
return a;
}
static void encryptAES(byte[] filesBytes, string filePath, AesCryptoServiceProvider aes)
{
using (FileStream fStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (ICryptoTransform crypt = aes.CreateEncryptor(aes.Key, aes.IV))
{
using (CryptoStream csStream = new CryptoStream(fStream, crypt, CryptoStreamMode.Write))
{
csStream.Write(filesBytes, 0, filesBytes.Length);
}
try {
File.Delete(filePath + ".encrypted");
File.Move(filePath, filePath + ".encrypted");
}
catch (UnauthorizedAccessException)
{
}
}
}
}
static void decryptAES(/*byte[] buffer,*/string filePath, byte[] key, byte[] IV)
{
using (AesCryptoServiceProvider AES = new AesCryptoServiceProvider())
{
AES.Padding = PaddingMode.PKCS7;
AES.Key = key;
AES.BlockSize = 128;
AES.KeySize = 128;
AES.IV = IV;
using (FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (ICryptoTransform crypt = AES.CreateDecryptor(key, IV))
{
using (CryptoStream crStream = new CryptoStream(fStream, crypt, CryptoStreamMode.Read))
{
using (StreamReader reader = new StreamReader(crStream))
{
//breaks here
string data = reader.ReadToEnd();
File.WriteAllText(filePath.Replace(".encrypted", ""), data);
}
}
}
}
}
}