2011-10-26 33 views
5

Tôi đang làm việc trên phần mềm mã hóa/giải mã các tệp. Tôi muốn có thể đoán được độ dài của dữ liệu sau khi mã hóa nhưng tôi không thể sử dụng CryptoStream.Length (Nó ném một NotSupportedException). Có cách nào để đoán không?Lấy chiều dài của một CryptoStream trong .Net

Tôi đang sử dụng RijndaelManaged (.Net Framework 4.0)

+0

FYI, xem http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts/ –

+0

tôi không thể nhớ, và nó có thể giúp trả lời câu hỏi - bạn có đang truyền một loại luồng cơ bản tới CryptoStream hay là nó đang ghi trực tiếp vào một tệp không? –

+0

Có một FileStream đọc tệp, CryptoStream nhận luồng đó, sau đó, CryptoStream được ghi vào một NetworkStream. Đó là lý do tại sao tôi cần phải biết kích thước để chia nó trong bộ đệm –

Trả lời

4

này nói nó tốt hơn nhiều so với tôi có thể http://www.obviex.com/Articles/CiphertextSize.aspx

Từ đó:

Trong trường hợp tổng quát nhất, kích thước của ciphertext có thể được tính như sau:

CipherText = PlainText + Block - (Khối chữ thường MOD)

trong đó CipherText, PlainText và Block cho biết kích thước của bản mã, văn bản thuần túy và khối mã hóa tương ứng. Về cơ bản, kích thước bản mã kết quả được tính như kích thước của bản rõ được mở rộng tới khối tiếp theo. Nếu padding được sử dụng và kích thước của bản rõ là một bội số chính xác của kích thước khối, một khối bổ sung chứa thông tin đệm sẽ được thêm vào.

Giả sử bạn muốn mã hóa số an sinh xã hội chín chữ số (SSN) bằng thuật toán mã hóa Rijndael với kích thước khối 128 bit (16 byte) và đệm PKCS # 7. (Với mục đích của hình minh họa, giả sử rằng dấu gạch ngang được loại bỏ khỏi giá trị SSN trước khi mã hóa, sao cho "123-45-6789" trở thành "123456789" và giá trị được coi là một chuỗi, không phải là số.) Nếu các chữ số trong SSN được định nghĩa là các ký tự ASCII, kích thước của bản mã có thể được tính như sau:

CipherText = 9 + 16 - (9 MOD 16) = 9 + 16 - 9 = 16 (bytes)

Lưu ý rằng nếu kích thước của giá trị thô là bội số chính xác của kích thước khối, một khối bổ sung chứa thông tin đệm sẽ được nối thêm vào bản mã. Ví dụ: nếu bạn muốn mã hóa số thẻ tín dụng gồm 16 chữ số (được định nghĩa là chuỗi ASCII 16 ký tự), kích thước của bản mã sẽ là:

CipherText = 16 + 16 - (16 MOD 16) = 16 + 16 - 0 = 32 (byte)

+0

+1 liên kết rất thú vị :-) – Yahia

+0

Cảm ơn, nhưng, tôi không mã hóa chuỗi nhưng tệp, có giống nhau không? –

+2

Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (http: //meta.stackexchange.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. –

0

Điều đó phụ thuộc vào mật mã bạn sử dụng ... thường là độ dài bằng với độ dài của luồng gốc ... worstcase là nó được đệm thành bội số của chiều dài khối của thuật toán mã hóa

+0

Có cách nào để đoán kích thước đó nếu tôi đang mã hóa tệp không? Vấn đề là tôi đang sử dụng Rijndael để chuyển các tệp với luồng mạng TCP và ở phía máy chủ tôi cần biết kích thước để rời khỏi vòng lặp –

+0

"đoán" (không chính xác) hoặc tính toán chính xác? – Yahia

+0

Tôi muốn tính toán chính xác? :) –

0

Đây là mã của tôi với RijndaelManaged:

MemoryStream textBytes = new MemoryStream(); 

string password = @"myKey123"; // Your Key Here 

UnicodeEncoding UE = new UnicodeEncoding(); 
byte[] key = UE.GetBytes(password); 

FileStream fsInput = new FileStream(@"C:\myEncryptFile.txt", FileMode.Open); 

RijndaelManaged RMCrypto = new RijndaelManaged(); 

CryptoStream cs = new CryptoStream(fsInput, RMCrypto.CreateDecryptor(key, key), 
            CryptoStreamMode.Read); 
cs.CopyTo(textBytes); 

cs.Close(); 
fsInput.Close(); 

string myDecriptText = Encoding.UTF8.GetString(textBytes.ToArray()); 
0

Bạn có thể sử dụng chức năng này để có được cả chiều dài và dữ liệu.

public static int GetLength(CryptoStream cs, out byte[] data) 
{ 
    var bytes = new List<byte>(); 

    int b; 
    while ((b = cs.ReadByte()) != -1) 
     bytes.Add((byte)b); 

    data = bytes.ToArray(); 

    return data.Length; 
} 
Các vấn đề liên quan