2016-06-30 13 views
11

Ich habe einen zufälligen 256-Bit-symmetrischen Schlüssel in einer Datei generiert, um einige Daten mit der OpenSSL-Befehlszeile zu verschlüsseln, die ich später programmgesteuert mithilfe der OpenSSL-Bibliothek entschlüsseln muss. Ich habe keinen Erfolg, und ich denke, das Problem könnte in dem Initialisierungsvektor liegen, den ich verwende (oder nicht verwende).Wie lautet die Standard-IV bei der Verschlüsselung mit der aes_256_cbc-Chiffre?

ich verschlüsseln die Daten mit diesem Befehl:

/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile 

ich den folgenden Aufruf bin mit der Entschlüsselung der Daten zu initialisieren:

EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr)) 

keyfile ist ein vector<unsigned char>, die die 32 Bytes hält des Schlüssels. Meine Frage bezieht sich auf diesen letzten Parameter. Es soll ein Initialisierungsvektor für den Verschlüsselungsalgorithmus sein. Ich habe beim Verschlüsseln keine IV angegeben, daher muss ein Standard verwendet worden sein.

Bedeutet das Übergeben von nullptr für diesen Parameter "den Standard verwenden"? Ist der Standardwert null und dem ersten Verschlüsselungsblock wird nichts hinzugefügt?

Ich sollte erwähnen, dass ich aus der Befehlszeile entschlüsseln kann, ohne eine IV zu liefern.

+0

Würde die Verwendung von IV (oder einem festen Standardwert) die Stärke der Verschlüsselung nicht ernsthaft untergraben? Nach meinem Verständnis besteht der Zweck der IV darin, sicherzustellen, dass der identische Klartext keinen identischen Chiffretext erzeugt. Es muss also ein IV sein, es muss nicht geheim sein, es muss nur für alles, was Sie verschlüsseln, einzigartig sein. Nicht einen (oder einen festen) zu verwenden klingt wie eine sehr schlechte Idee. –

+0

Ich bin kein Kryptograf, noch spiele ich einen im Fernsehen, deshalb bin ich wirklich nicht qualifiziert zu antworten (daher warum das obige nur ein Kommentar war).Als Nicht-Experte würde ich raten, dass, solange der Schlüssel jedes Mal einzigartig ist, es wahrscheinlich in Ordnung ist, aber dann als Pragmatiker, der weiß, dass er zu wenig über Verschlüsselung weiß, würde ich wahrscheinlich auch einen zufälligen IV verwenden. trotzdem * und speichern Sie es zusammen mit den verschlüsselten Daten. –

+0

Ich habe einige Informationen darüber gefunden: [Antwort auf crypto.stackexchange.com In Bezug auf die Verwendung der gleichen IV mit verschiedenen Schlüsseln für jeden Klartext.] (Http://crypto.stackexchange.com/questions/8600/why-shouldi-i- use-an-initialization-vector-iv-wenn-ich-habe-eindeutige-keys) – Steve

Antwort

6

Was ist die Standard IV beim Verschlüsseln mit EVP_aes_256_cbc() [sic] cipher ...

Bedeutet das Übergeben von nullptr für diesen Parameter "den Standard verwenden"? Ist der Standardwert null und dem ersten Verschlüsselungsblock wird nichts hinzugefügt?

Es gibt keine. Du musst es liefern. Der Vollständigkeit halber sollte die IV nicht vorhersehbar sein.

nicht vorhersagbaren ist etwas anders als die beiden Einzigartige und Zufall. Zum Beispiel benutzte SSLv3 den letzten Block des Geheimtextes für die IV des nächsten Blocks. Es war Unique, aber es war weder Random noch Non-Predictable, und es machte SSLv3 anfällig für ausgewählte Klartext-Angriffe.

Andere Bibliotheken machen clevere Dinge wie einen Nullvektor (eine Folge von Nullen). Ihre Angreifer danken ihnen dafür. Siehe auch Why is using a Non-Random IV with CBC Mode a vulnerability? auf Stack Overflow und Is AES in CBC mode secure if a known and/or fixed IV is used? auf Crypto.SE.


/usr/bin/openssl enc -aes-256-cbc...

Ich sollte erwähnen, dass ich in der Lage bin von der Kommandozeile aus zu entschlüsseln, ohne eine IV zu liefern.

OpenSSL verwendet eine interne Mashup/Schlüsselableitungsfunktion, die das Passwort übernimmt und einen Schlüssel und iv ableitet. Es heißt EVP_BytesToKey, und Sie können darüber in den man-Seiten lesen. Die Man-Pages auch sagen:

Wenn die Gesamt Schlüssel und IV Länge kleiner ist als die Länge Digest und MD5 verwendet wird, dann wird der Ableitungsalgorithmus ist kompatibel mit PKCS # 5 v1.5 sonst eine Nicht-Standard-Erweiterung wird verwendet, um leiten Sie die zusätzlichen Daten ab.

Es gibt viele Beispiele für EVP_BytesToKey sobald Sie wissen, was Sie suchen. Openssl password to key ist eine in C. How to decrypt file in Java encrypted with openssl command using AES in einem in Java.


EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))

Ich habe keine IV geben Sie bei der Verschlüsselung, so dass einige standardmäßig verwendet worden sein.

Überprüfen Sie Ihre Rückgabewerte. Ein Anruf sollte irgendwo auf dem Pfad fehlgeschlagen sein. Vielleicht nicht bei EVP_DecryptInit_ex, aber sicherlich vor EVP_DecryptFinal.

Wenn es nicht fehlschlägt, dann bitte einen Fehlerbericht.

+0

Es ist nicht bis EVP_DecryptFinal fehlgeschlagen. Das sind viele gute Informationen, danke! – Steve

5

EVP_DecryptInit_ex ist eine Schnittstelle zum AES-Entschlüsselungsprimitiv. Das ist nur ein Teil dessen, was Sie benötigen, um das OpenSSL-Verschlüsselungsformat zu entschlüsseln. Das OpenSSL-Verschlüsselungsformat ist nicht gut dokumentiert, aber Sie können es aus dem Code und einigen Dokumenten zurückverarbeiten. Der Schlüssel und IV Berechnung wird in der EVP_BytesToKey Dokumentation erläutert:

The key and IV is derived by concatenating D_1, D_2, etc until enough 
    data is available for the key and IV. D_i is defined as: 

      D_i = HASH^count(D_(i-1) || data || salt) 

    where || denotes concatentaion, D_0 is empty, HASH is the digest 
    algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is 
    HASH(HASH(data)) and so on. 

    The initial bytes are used for the key and the subsequent bytes for the 
    IV. 

"HASH" hier ist MD5. In der Praxis bedeutet dies, Sie Hashes wie folgt berechnen:

Hash0 = '' 
Hash1 = MD5(Hash0 + Password + Salt) 
Hash2 = MD5(Hash1 + Password + Salt) 
Hash3 = MD5(Hash2 + Password + Salt) 
... 

Dann ziehen Sie die Bytes, die Sie für den Schlüssel benötigen, und ziehen Sie dann die Bytes, die Sie für die IV benötigen. Für AES-128 bedeutet das, Hash1 ist der Schlüssel und Hash2 ist der IV. Für AES-256 ist der Schlüssel Hash1 + Hash2 (verkettet, nicht hinzugefügt) und Hash3 ist der IV.

Sie müssen den führenden Salted___ Header entfernen, dann verwenden Sie das Salz, um den Schlüssel und IV zu berechnen. Dann haben Sie die Stücke in EVP_DecryptInit_ex zu füttern.

Da Sie dies in C++ tun, können Sie wahrscheinlich nur den enc Code durchsuchen und ihn wiederverwenden (nachdem Sie überprüft haben, dass seine Lizenz mit Ihrer Verwendung kompatibel ist).

Beachten Sie, dass OpenSSL IV zufällig generiert wird, da es sich um die Ausgabe eines Hashing-Prozesses handelt, der ein zufälliges Salz beinhaltet. Die Sicherheit des ersten Blocks hängt nicht davon ab, dass die IV per se zufällig ist; es erfordert nur, dass ein bestimmtes IV + Schlüsselpaar niemals wiederholt wird. Der OpenSSL-Prozess stellt sicher, dass das zufällige Salz niemals wiederholt wird.

Es ist möglich, dass die Verwendung von MD5 auf diese Weise den Schlüssel und IV in einer Weise verschlingt, die Informationen leckt, aber ich habe noch nie eine Analyse gesehen, die das behauptet. Wenn Sie das OpenSSL-Format verwenden müssen, würde ich keine Bedenken hinsichtlich seiner IV-Generation haben. Das große Problem mit dem OpenSSL-Format ist, dass es schnell zu roher Gewalt ist (4 Runden von MD5 reichen nicht aus) und es fehlt jegliche Authentifizierung.

+0

Uh Alter, Sie haben den Quellcode und Sie nennen das Reverse Engineering? – Pacerier

+0

Irgendeine Idee, wie aes 256 hier mit einem 256 Bit IV arbeitet? Mein Verständnis ist, dass die IV 128 Bit und der Schlüssel 256 Bit sein muss. Im obigen Pseudo sind beide 256 Bit korrekt. – Aaron

+1

@Aaron aktualisiert. Die 256-Bit-IV war falsch. Es funktionierte gut wegen der Bibliotheken, mit denen ich arbeitete, aber nur die ersten 128-Bit wurden tatsächlich verwendet. –