在c#

时间:2017-08-25 13:50:28

标签: c# exception encryption

我正在构建一个可以在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密钥存储在我的资源文件中,然后使用它来解密密钥。 感谢

2 个答案:

答案 0 :(得分:0)

到目前为止,这么好。您是否提取生成的KeyIV?我将您的解密功能修改为加密功能......

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.WriteAllTextFile.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);
                        }
                    }
                }
            }
        }
    }