2011-06-23 14 views
6

Tôi cần chuyển các tệp xml và chúng được yêu cầu phải được mã hóa. Tôi đã tìm thấy một số ví dụ nghĩ rằng tôi là gần gũi nhưng khi tôi giải mã các tập tin tôi kết thúc với ký tự rác sau. Có một số bài viết về điều này nhưng tôi đã không nhìn thấy bất kỳ mà sẽ chính xác giúp đỡ. Đây là mã hóa và giải mã.Sử dụng Rijndael để mã hóa/giải mã các tệp

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!"); 
} 

tôi kết thúc với

<?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 

Trả lời

10

Khi giải mã, hãy chú ý đến giá trị trả về từ cuộc gọi CryptoStream.Đọc. Nó cho bạn biết độ dài của dữ liệu được giải mã trong mảng byte của bạn (thường sẽ không khớp với độ dài của dữ liệu được mã hóa do đệm). Hãy thử sử dụng các chức năng sau trong hàm giải mã của bạn:

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); 
+0

Và chúng tôi có một người chiến thắng !!!! Cảm ơn anh rất nhiều! – mjames

2

Trên đối tượng RijndaelManaged, thiết lập Padding tài sản để PaddingMode.ANSIX923 hoặc PaddingMode.ISO10126.

Các byte trống đó đã được thêm vào để điền vào khối được mã hóa cuối cùng. Nó được đệm với số không theo mặc định, có nghĩa là không có dấu hiệu nào được đưa ra theo độ dài thực tế của dữ liệu. Các chế độ đệm khác bao gồm độ dài trong byte cuối cùng, do đó có thể xóa lớp đệm sau khi giải mã.

Đặt thuộc tính đệm trong cả thường trình mã hóa và giải mã thành cùng một giá trị.

rijndaelCSP.Padding = PaddingMode.ANSIX923; 

Nếu biết điều gì sẽ xảy ra, thì luồng giải mã sẽ tự động xóa lớp đệm, vì vậy không cần thay đổi thêm.

CẬP NHẬT

Từ nhìn vào mã của bạn, dường như số byte mà bạn đang viết vào tập tin đầu ra là bằng với số byte đọc từ tập tin đầu vào.

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

Quy trình giải mã sẽ không điền đầy đủ vào mảng inputFileData do đệm trong đầu vào.

Luồng đầu ra sẽ ghi lại toàn bộ chiều dài của bộ đệm, mặc dù nó không được lấp đầy hoàn toàn.

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

Đây là nguồn của các giá trị rỗng của bạn.

Bạn có thể muốn thay đổi cách bạn đang thực hiện mã hóa và giải mã để nó không còn sử dụng bộ đệm có độ dài cố định. Ngoài ra, bạn có thể lưu trữ độ dài của dữ liệu được mã hóa lúc đầu và chỉ ghi số byte tương ứng với độ dài đó.

+0

+1 Tôi đã tham gia vào quá trình này trong quá khứ. Tôi tin rằng đây là giải pháp tôi đã sử dụng để khắc phục. –

+0

Tôi đã thử cả hai chế độ đệm và nhận được kết quả tương tự. – mjames