2011-10-26 9 views
5

Pracuję nad oprogramowaniem, które szyfruje/odszyfrowuje pliki. Chciałbym móc odgadnąć długość danych po szyfrowaniu, ale nie mogę użyć CryptoStream.Length (To rzuca wyjątek NotSupportedException). Czy istnieje sposób, aby to odgadnąć?Uzyskaj długość CryptoStream w .Net

Używam RijndaelManaged (.NET Framework 4.0)

+0

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

+0

nie mogę sobie przypomnieć, i może pomóc w odpowiedzi na pytanie - czy przekazujesz podstawowy strumień do CryptoStream, czy też pisze on bezpośrednio do pliku? –

+0

Istnieje FileStream, który odczytuje plik, CryptoStream pobiera ten strumień, po czym CryptoStream jest zapisywany do NetworkStream. Dlatego muszę znać rozmiar, aby podzielić go w buforze –

Odpowiedz

4

Mówi to o wiele lepiej niż ja http://www.obviex.com/Articles/CiphertextSize.aspx

Stamtąd:

W najbardziej rodzajowego przypadku wielkość zaszyfrowany można obliczyć jako:

szyfrogram = plainText + blokowanie - (plainText MOD Blok)

gdzie CipherText, PlainText i Block wskazują odpowiednio rozmiary szyfrogramu, jawnego tekstu i bloku szyfrowania. Zasadniczo wynikowy rozmiar tekstu zaszyfrowanego jest obliczany jako rozmiar tekstu jawnego rozszerzonego do następnego bloku. Jeśli użyte zostanie wypełnienie, a rozmiar zwykłego tekstu jest dokładną wielokrotnością rozmiaru bloku, zostanie dodany jeden dodatkowy blok zawierający informacje o dopełnieniu.

Załóżmy, że chcesz zaszyfrować dziewięciocyfrowy numer Social Security (SSN) za pomocą algorytmu szyfrowania Rijndael z 128-bitowym (16-bajtowym) rozmiarem bloku i dopełnieniem PKCS # 7. (Na potrzeby ilustracji załóżmy, że kreski są usuwane z wartości SSN przed szyfrowaniem, tak że "123-45-6789" staje się "123456789", a wartość jest traktowana jako ciąg, a nie jako liczba.) Jeżeli cyfry SSN są grupy znaków ASCII wielkość zaszyfrowanego tekstu może być obliczona jako:

szyfrogram = 9 + 16 - (9 MOD 16) = 9 + 16 - 9 = 16 (bajty)

Należy zauważyć, że jeśli rozmiar jawnego tekstu jest dokładną wielokrotnością rozmiaru bloku, dodatkowy blok zawierający informacje o dopełnieniu zostanie dołączony do zaszyfrowanego tekstu. Na przykład, jeśli chcesz zaszyfrować 16-cyfrowy numer karty kredytowej (zdefiniowany jako 16-znakowy ciąg ASCII), rozmiar zaszyfrowanego tekstu będzie wynosił:

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

+0

+1 bardzo fajny link :-) – Yahia

+0

Dzięki, ale nie koduję ciągów ale pliki, czy to to samo? –

+2

Chociaż może to teoretycznie odpowiedzieć na pytanie, [byłoby lepiej (http: //meta.stackexchange.com/q/8259), aby uwzględnić istotne części odpowiedzi tutaj, i podać odsyłacz dla odniesienia. –

0

To zależy od szyfru, którego używasz ... zazwyczaj długość jest taka sama jak długość oryginalnego strumienia ... najgorsze jest to, że jest dopełniana do wielokrotności długość bloku szyfru

+0

Czy istnieje sposób na zgadnięcie tego rozmiaru, jeśli koduję plik? Problem polega na tym, że używam Rijndael do przesyłania plików ze strumieniem sieci TCP, a po stronie serwera muszę znać rozmiar, aby opuścić pętlę –

+0

"zgadnij" (niezbyt dokładnie) lub dokładnie obliczyć? – Yahia

+0

Chciałbym dokładnie ukuć? :) –

0

to jest mój kod z 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

Możesz użyć tej funkcji, aby uzyskać zarówno długość, jak i dane.

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; 
} 
Powiązane problemy