使用Rijndael加密/解密文件

问题描述

| 我需要传输xml文件,并且需要对其进行加密。我发现一些例子认为我已经接近了,但是当我解密文件时,我最终得到了结尾的垃圾字符。有一些关于此的帖子,但是我还没有看到任何可以提供确切帮助的帖子。这是加密和解密代码
private void EncryptFile(string inputFile,string outputFile,string key) {
    try {
        byte[] keyBytes;
        keyBytes = Encoding.Unicode.GetBytes(key);

        Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key,keyBytes);

        RijndaelManaged rijndaelCSP = new RijndaelManaged();
        rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
        rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);

        ICryptoTransform encryptor = rijndaelCSP.CreateEncryptor();

        FileStream inputFileStream = new FileStream(inputFile,FileMode.Open,FileAccess.Read);

        byte[] inputFileData = new byte[(int)inputFileStream.Length];
        inputFileStream.Read(inputFileData,(int)inputFileStream.Length);

        FileStream outputFileStream = new FileStream(outputFile,FileMode.Create,FileAccess.Write);

        CryptoStream encryptStream = new CryptoStream(outputFileStream,encryptor,CryptoStreamMode.Write);
        encryptStream.Write(inputFileData,(int)inputFileStream.Length);
        encryptStream.FlushFinalBlock();

        rijndaelCSP.Clear();
        encryptStream.Close();
        inputFileStream.Close();
        outputFileStream.Close();
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message,\"Encryption Failed!\",MessageBoxButtons.OK,MessageBoxIcon.Error);
        return;
    }

    MessageBox.Show(\"File Encryption Complete!\");

}

private void DecryptFile(string inputFile,string key) {
    try {
        byte[] keyBytes = Encoding.Unicode.GetBytes(key);

        Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key,keyBytes);

        RijndaelManaged rijndaelCSP = new RijndaelManaged();
        rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
        rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);
        ICryptoTransform decryptor = rijndaelCSP.CreateDecryptor();

        FileStream inputFileStream = new FileStream(inputFile,FileAccess.Read);

        CryptoStream decryptStream = new CryptoStream(inputFileStream,decryptor,CryptoStreamMode.Read);

        byte[] inputFileData = new byte[(int)inputFileStream.Length];
        decryptStream.Read(inputFileData,FileAccess.Write);
        outputFileStream.Write(inputFileData,inputFileData.Length);
        outputFileStream.Flush();

        rijndaelCSP.Clear();

        decryptStream.Close();
        inputFileStream.Close();
        outputFileStream.Close();
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message,\"Decryption Failed!\",MessageBoxIcon.Error);
        return;
    }

    MessageBox.Show(\"File Decryption Complete!\");
}
我最终
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<transaction>
  <header>
    <qOrderNumber></qOrderNumber>
    <qRequestDate></qRequestDate>
    <testOrder></testOrder>
    <qCustomerNumber></qCustomerNumber>
    <transactionStatus></transactionStatus>
  </header>
  <lines>
    <line>
      <productID></productID>
      <serialNumber></serialNumber>
    </line>
    <line> 
      <productID></productID>
      <serialNumber></serialNumber>
    </line>
  </lines>
</transaction>NULNULNULNULNULNUL
    

解决方法

        解密时,请注意CryptoStream.Read调用的返回值。它告诉您字节数组中解密数据的长度(由于填充,通常不会与加密数据的长度匹配)。尝试在解密函数中使用以下命令:
int decrypt_length = decryptStream.Read(inputFileData,(int)inputFileStream.Length);
FileStream outputFileStream = new FileStream(outputFile,FileMode.Create,FileAccess.Write);
outputFileStream.Write(inputFileData,decrypt_length);
    ,        在“ 3”对象上,将“ 4”属性设置为“ 5”或“ 6”。 这些空字节被添加以填充最终的加密块。默认情况下,它用零填充,这意味着没有指示数据的实际长度。其他填充模式包括最后一个字节的长度,以便可以在解密后删除填充。 将加密和解密例程中的padding属性设置为相同的值。
 rijndaelCSP.Padding = PaddingMode.ANSIX923;
如果知道期望什么,那么解密流将自动删除填充,因此不需要进一步的更改。 更新 通过查看代码,您似乎正在写入输出文件的字节数等于从输入文件读取的字节数。
byte[] inputFileData = new byte[(int)inputFileStream.Length];
decryptStream.Read(inputFileData,(int)inputFileStream.Length);
由于输入中的填充,解密过程不会完全填满“ 9”数组。 然后,即使没有完全填充输出流,它也会写出缓冲区的整个长度。
outputFileStream.Write(inputFileData,inputFileData.Length);
这是空值的来源。 您可能需要更改进行加密和解密的方式,以使其不再使用固定长度的缓冲区。或者,您可以在开始时存储加密数据的长度,并仅写入与该长度相对应的字节数。