Witam,
mam zaszyfrowany tekst przez AES (mode CBC) oraz znam input vector (w kodzie programu jest to stałą wartość, key_length 16).
Jak z czymś takim sobie poradzić? Czy jest możliwe odszyfrowanie bez klucza?
Całym zamysłem szyfrów jest to by system był bezpieczny nawet jak są znane wszystkie parametry oprócz klucza. Chyba to odpowiada na Twoje pytanie.
A znasz pierwsze znaki zaszyfrowanego tekstu? Można próbować brute forcem i porównywać wynik z tym czego się spodziewasz. Jest to uzależnione od długości klucza, np. przy 56 bitach jest to nawet realne. Ile bitów ma klucz?
nalik napisał(a):
A znasz pierwsze znaki zaszyfrowanego tekstu? Można próbować brute forcem i porównywać wynik z tym czego się spodziewasz. Jest to uzależnione od długości klucza, np. przy 56 bitach jest to nawet realne. Ile bitów ma klucz?
Pierwsze znakie są w stylu: "v`ţ2iÚ" [7660FE3269]
Co do klucza, z analizy kodu wynika (jest tak, że przez md5 jest haszowany ciąg od usra + dochodzi Default_key [czyli IV]), że jest tworzona tablica byte o rozmiarze 16 (c# new byte[16]) tam jest przechowywany miks z inputu i iv.
edit (nie mogę więcej udostępnić):
key_length = 16;
user_key = this.CombineKeys(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(str))); // metoda CombineKeys właśnie zwraca byte[16]
Nie da rady z samego ciphertextu. Masz tutaj zupełnie losowy 128 bitowy klucz i jest to zupełnie nie do ruszenia nawet przez NSA. Można by coś podziałać, gdybyś np. miał dostęp do serwera który pozwala szyfrować/deszyfrować z tym samym kluczem, albo gdyby ten AES miał ograniczoną liczbę rund, ale w twoim przypadku mozesz zapomnieć o złamaniu tego.
Wychodzi na to, że klucz to powtórzenie 4 bajtów.
byte[] bytes2 (+ 3, 4, 5) = BitConverter.GetBytes(num);
for (int i = 0; i < 4; i++)
{
key[i] = bytes2[i];
key[i + 4] = bytes3[i];
key[i + 8] = bytes4[i];
key[i + 12] = bytes5[i];
}
Czy to upraszcza sprawę?
Edit:
Czy dobrze rozumiem, że jak mam zaszyfrowany string, to pierwsze 16 bajtów to iv?
- Nie widzę skąd wnioskujesz że to powtórzenie 4 bajtów. Kod wyżej nic takiego nie mówi.
- Tak, zwykle w AES-CBC i podobnych szyfrowaniach podaje się IV jako pierwszy blok.
Shalom napisał(a):
- Nie widzę skąd wnioskujesz że to powtórzenie 4 bajtów. Kod wyżej nic takiego nie mówi.
- Tak, zwykle w AES-CBC i podobnych szyfrowaniach podaje się IV jako pierwszy blok.
ad.1 Używana jest tylko zmienna num, która jest typu "int" (32byte).
// Różne operacje, które po analizie pokazują, że klucz jest budowany z 1 zmiennej "num"
byte[] bytes2 = BitConverter.GetBytes(num)
byte[] bytes3 = BitConverter.GetBytes(num);
byte[] bytes4 = BitConverter.GetBytes(num);
byte[] bytes5 = BitConverter.GetBytes(num);
byte[] key= new byte[16];
for (int i = 0; i < 4; i++)
{
key[i] = bytes2[i];
key[i + 4] = bytes3[i];
key[i + 8] = bytes4[i];
key[i + 12] = bytes5[i];
}
Edit:
Brute force to trochę kiepski pomysł, bo trzeba przeglądać od 0 do 0x99999999. Istnieje inna możliwość?
I co to za problem? 32 bity to się brutuje szybko, szczególnie jak masz nie jakiś archaiczne CPU, bo już od dawna są CPU że sprzętowym wsparciem dla aesa. No i możesz to jeszcze liczyć równolegle. Zdajesz sobie sprawę z tego że twój procesor potrafi wykonać miliardy operacji na sekundę? :)
Shalom napisał(a):
I co to za problem? 32 bity to się brutuje szybko, szczególnie jak masz nie jakiś archaiczne CPU, bo już od dawna są CPU że sprzętowym wsparciem dla aesa. No i możesz to jeszcze liczyć równolegle. Zdajesz sobie sprawę z tego że twój procesor potrafi wykonać miliardy operacji na sekundę? :)
Wiem, wiem ;) tylko szukam alternatywnych metod, bo gdyby kiedyś coś było cięższego do rozwiązania.
Generalnie skrypt w pythone + 4 threads = 5h - tyle zajęło zdeszyfrowanie (cpu mobilne i5)