Forum Linux.pl

Oprogramowanie => Multimedia => Wątek zaczęty przez: tinware w 2017-11-13, 23:06:44

Tytuł: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: tinware w 2017-11-13, 23:06:44
Cześć,

Chciałem odszyfrować plik przy użyciu openssl.

To jest moja playlista HLS (.m3u8). Lista zawiera 9-cio sekundowy fragment filmu, który jest zaszyfrowany i odtworzenie go bezpośrednio nie jest możliwe. Odszyfrowanie odbywa się za pomocą danych zawartych w pierwszej linijce, czyli metody, klucza i wektora:

Cytuj
#EXT-X-KEY:METHOD=AES-128,URI="key/01.key",IV=0x00000000000000000000015FA0E49B00
#EXTINF:9.480,
segment/01.ts

Na podstawie tej listy tworzę komendę:
openssl aes-128-cbc -in "segment/01.ts" -out decrypted.ts -iv 0x00000000000000000000015FA0E49B00 -K "key/01.key"

Wynikiem jest otrzymany błąd:
Cytuj
hex string is too long
invalid hex iv value

W jaki sposób mogę rozwiązać ten problem? Czy potrzebna jest konwersja liczby IV? Jeśli tak, to z jakiej na jaką (hexadecymalną)?

Do postu załączam plik źródłowy:
http://www26.zippyshare.com/v/VyurKv7c/file.html (http://www26.zippyshare.com/v/VyurKv7c/file.html)

Proszę o pomoc
Dziękuję
Tytuł: Odp: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: Paweł Kraszewski w 2017-11-14, 07:17:33
Jeżeli wszystko inne zawiedzie, przeczytaj instrukcję.

Cytuj
-iv IV

The actual IV to use: this must be represented as a string comprised only of hex digits. When only the key is specified using the -K option, the IV must explicitly be defined. When a password is being specified using one of the other options, the IV is generated from this password.

Wywal 0x z początku i powinno być dobrze. Dla standardowego AES, wektor IV ma 16 bajtów, czyli 32 cyfry HEX - to się zgadza.
Tytuł: Odp: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: 1709 w 2017-11-14, 14:04:50
Przepraszam ze sie wtrace.
Jesli sie nie myle to jest szyfrowanie symetryczne , tak ?
A nie lepiej pliki szyfrowac asymetrycznie ?
Czy jest to tylko kwestia wygody ?
Tytuł: Odp: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: Paweł Kraszewski w 2017-11-14, 15:14:33
Przepraszam ze sie wtrace.
Jesli sie nie myle to jest szyfrowanie symetryczne , tak ?
A nie lepiej pliki szyfrowac asymetrycznie ?
Czy jest to tylko kwestia wygody ?

O ile się orientuję, plik jest skierowany do wielu odbiorców, wtedy szyfrowanie asymetryczne nie ma uzasadnienia.

Od strony technicznej - w przypadku GPG/PGP/SMIME dane są zaszyfrowane algorytmem symetrycznym z losowym kluczem, i dopiero ten klucz jest szyfrowany algorytmem asymetrycznym. Wynika to ze złożoności obliczeniowej algorytmu asymetrycznego - nie nadaje się do szyfrowania dużych paczek danych.
Tytuł: Odp: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: tinware w 2017-11-15, 00:00:39
Dzięki za aktywność.
Temat poruszam już od dłuższego czasu w różnych miejscach, niestety nikt nie potrafi mi pomóc.



Jeżeli wszystko inne zawiedzie, przeczytaj instrukcję.
Naturalnie, że już się z nią zapoznałem, przynajmniej z tą częścią dokumentacji dotyczącej #EXT-X-KEY.



O ile się orientuję, plik jest skierowany do wielu odbiorców
Potwierdzam.



Od strony technicznej - w przypadku GPG/PGP/SMIME dane są zaszyfrowane algorytmem symetrycznym z losowym kluczem, i dopiero ten klucz jest szyfrowany algorytmem asymetrycznym.
Wydaje mi się, że HTTP Live Stream jest obecnie najbardziej popularną metodą publikowania plików wideo w sieci. Opatentowało to Apple. Mając 10 minutowy filmik, dzielimy go na np. 100 segmentów po 6 sekund każdy. Przepisem do jego odtworzenia jest playlista w formacie pliku M3U8 (rozszerzona lista M3U). HLS ma różne opcję, na przykład -> klucze szyfrujące. Nagłówek z kluczem zmienia się np. co 10 segmentów, tzn. dla pierwszych 10 segmentów metoda, klucz i wektor będzie inny niż dla 11, 12... 20 segmentu oraz inny dla 21-30 segmentów.



Wywal 0x z początku i powinno być dobrze

A więc:
openssl aes-128-cbc -in "segment/01.ts" -out decrypted.ts -iv 00000000000000000000015FA0E49B00 -K "key/01.key"

Otrzymuję odpowiedź:
Cytuj
non-hex digit
invalid hex key value

Idąc tym tropem przekonwertowałem binarną wartość pliku z kluczem na hex. Użyłem do tego PHP i funkcji bin2hex() (http://php.net/manual/en/function.bin2hex.php). Otrzymałem następujący ciąg liczb: e8eb81dc582245da205801e377daf56a.

Jeszcze raz:
openssl aes-128-cbc -in "segment/01.ts" -out decrypted.ts -iv 00000000000000000000015FA0E49B00 -K e8eb81dc582245da205801e377daf56a

Wynik bez błędów. Niestety, otrzymany plik nie odtwarza się, nie ma on nawet swojej miniaturki (screenshot) w folderze z plikami. Rozmiar otrzymanego pliku 16 bajtów większy niż rozmiar segmentu przed odszyfrowaniem.



Postanowiłem spróbować jeszcze w PHP. Nie jest to forum programistyczne, ale zamieszczę kod, ponieważ jest prosty:
<?php
$segment = file_get_contents("segment/01.ts");
$key_method = "AES-128-CBC";
$key_value = file_get_contents("key/01.key");
$key_iv = 0x00000000000000000000015FA0E49B00;

$decrypted = openssl_decrypt($segment, $key_method, $key_value, OPENSSL_RAW_DATA, $key_iv);

Otrzymałem odpowiedź:
Cytuj
Warning: openssl_decrypt(): IV passed is only 13 bytes long, cipher expects an IV of precisely 16 bytes, padding with \0 in /path/to/file/decrypted_01.php on line 7

Jak widać wynik programu zawiera błąd. Otrzymany plik odtwarza się tylko w niektórych programach i posiada on swoją miniaturkę (screenshot) w folderze z plikami. Rozmiar otrzymanego pliku 8 bajtów mniejszy niż rozmiar segmentu przed odszyfrowaniem.



Próbuję ze zmianą IV:
Cytuj
$key_iv = "0x00000000000000000000015FA0E49B00"; // 0x00000000000000000000015FA0E49B00
// Warning: openssl_decrypt(): IV passed is 34 bytes long which is longer than the 16 expected by selected cipher, truncating...

$key_iv = "00000000000000000000015FA0E49B00"; // 00000000000000000000015FA0E49B00
// Warning: openssl_decrypt(): IV passed is 32 bytes long which is longer than the 16 expected by selected cipher, truncating...

$key_iv = 0x00000000000000000000015FA0E49B00; // 1510232857344
// Warning: openssl_decrypt(): IV passed is only 13 bytes long, cipher expects an IV of precisely 16 bytes, padding with \0...

$key_iv = 00000000000000000000015FA0E49B00;
// błąd składni, interpreter kończy pracę na tej lini



W ramach testu spróbowałem podać losową wartość IV, np. 1234567890123456. Za każdym razem zwraca on prawie prawidłowy, działający plik. Prawie, ponieważ nie odtwarza się on wszędzie i uważam, że nie jest to wina kodeków, a raczej błędu odszyfrowania, skoro działa on zawsze, nawet przy losowej wartości wektora (IV). W linku zamieszczam otrzymane wyniki:
http://www119.zippyshare.com/v/U2XF8Fdl/file.html (http://www119.zippyshare.com/v/U2XF8Fdl/file.html)


Proszę Was o dalszą pomoc, gdyż nie mam pojęcia z której strony ugryźć ten problem.
Dziękuję za dotychczasową aktywność.
Tytuł: Odp: OPENSSL - problem z odszyfrowaniem pliku
Wiadomość wysłana przez: Paweł Kraszewski w 2017-11-15, 07:39:23
1. Przez instrukcję miałem na myśli instrukcję do openssl-a (https://www.openssl.org/docs/manmaster/man1/enc.html), gdzie przeczytałbyś

Cytuj
-K key

           the actual key to use: this must be represented as a string comprised only of hex digits.  (...)

Klucz w hex, nie plik z kluczem (to opcja -kfile PLIK_Z_KLUCZEM)

2. Jak widać, nie przeczytałeś też instrukcji openssl_decrypt (https://secure.php.net/manual/en/function.openssl-decrypt.php), gdzie napisane jest jak wół, że IV jest binarnym stringiem (vector w dokumentacji PHP to string zawierający surowe dane). W komentarzach możesz znaleźć $iv=hex2bin('IV-w-hex');

3. Tryb CBC ma to do siebie, że błędny IV psuje pierwszy blok odszyfrowania (pierwsze 16 bajtów w "podręcznikowym" AES*), następne odszyfrowują się poprawnie. Po prostu nie wszystkie programy odtwarzające radzą sobie z krzakami jako pierwsze 16 bajtów pliku.

* Piszę podręcznikowym, bo sam algorytm Rijndael (https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (tak się naprawdę nazywa algorytm pracujący w środku AES) przewiduje bloki o długości innej, niż 128 bitów, ale po ustandaryzowaniu AES występuje tylko wersja 128-bitowa. AES128, AES192 i AES256 to długości klucza, nie bloku danych.