7

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, 0, (int)inputFileStream.Length);

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

        CryptoStream encryptStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write);
        encryptStream.Write(inputFileData, 0, (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 outputFile, 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, FileMode.Open, FileAccess.Read);

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

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

        FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
        outputFileStream.Write(inputFileData, 0, inputFileData.Length);
        outputFileStream.Flush();

        rijndaelCSP.Clear();

        decryptStream.Close();
        inputFileStream.Close();
        outputFileStream.Close();
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message, "Decryption Failed!", MessageBoxButtons.OK, 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
4

2 に答える 2

11

復号化するときは、CryptoStream.Read呼び出しからの戻り値に注意してください。バイト配列内の復号化されたデータの長さを示します(通常、パディングのために暗号化されたデータの長さと一致しません)。復号化機能で以下を使用してみてください。

int decrypt_length = decryptStream.Read(inputFileData, 0, (int)inputFileStream.Length);
FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
outputFileStream.Write(inputFileData, 0, decrypt_length);
于 2011-06-23T21:46:12.643 に答える
3

RijndaelManagedオブジェクトで、PaddingプロパティをPaddingMode.ANSIX923またはに設定しますPaddingMode.ISO10126

これらのヌルバイトは、最終的な暗号化ブロックを埋めるために追加されました。デフォルトではゼロが埋め込まれています。これは、データの実際の長さについては示されていないことを意味します。他のパディングモードでは、最後のバイトに長さが含まれるため、復号化後にパディングを削除できます。

暗号化ルーチンと復号化ルーチンの両方でパディングプロパティを同じ値に設定します。

 rijndaelCSP.Padding = PaddingMode.ANSIX923;

何が期待できるかがわかっている場合、復号化ストリームは自動的にパディングを削除するため、それ以上の変更は必要ありません。

アップデート

コードを見ると、出力ファイルに書き込んでいるバイト数は、入力ファイルから読み込まれているバイト数に等しいように見えます。

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

inputFileData入力にパディングがあるため、復号化プロセスで配列が完全にいっぱいになることはありません。

出力ストリームは、完全に満たされていない場合でも、バッファーの全長を書き出します。

outputFileStream.Write(inputFileData, 0, inputFileData.Length);

これがnullの原因です。

固定長のバッファーを使用しないように、暗号化と復号化の方法を変更することをお勧めします。または、暗号化されたデータの長さを最初に格納し、その長さに対応するバイト数のみを書き込むこともできます。

于 2011-06-23T21:32:54.320 に答える