PyCrypto problem mit AES+CTR
Ich Schreibe ein Stück-code, der zum verschlüsseln einen text mithilfe der symmetrischen Verschlüsselung. Aber es kommt doch nicht wieder mit dem richtigen Ergebnis...
from Crypto.Cipher import AES
import os
crypto = AES.new(os.urandom(32), AES.MODE_CTR, counter = lambda : os.urandom(16))
encrypted = crypto.encrypt("aaaaaaaaaaaaaaaa")
print crypto.decrypt(encrypted)
Hier der entschlüsselte text ist anders als das original.
Verstehe ich nicht wirklich viel über Kryptographie, also bitte Geduld mit mir. Ich verstehe die CTR-Modus erfordert ein "Zähler" - Funktion, um die Versorgung ein random counter jedes mal, aber warum muss Sie es werden 16 bytes, wenn mein key ist 32 bytes und es besteht darauf, dass meine Nachricht wird in vielfachen von 16 bytes zu? Ist das normal?
Ich vermute, dass es nicht wieder zu der ursprünglichen Nachricht, da der Zähler verändert zwischen verschlüsseln und entschlüsseln. Aber dann, wie soll es theoretisch funktionieren überhaupt? Was mache ich falsch? Wie auch immer, ich bin gezwungen zum resort zurück, dass die EZB bis ich das herausgefunden 🙁
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
counter
muss zurück, das gleiche bei der Entschlüsselung wie bei der Verschlüsselung, wie Sie intuit, so dass man (NICHT SICHER) Weg, es zu tun ist:CTR ist ein block Ziffer, also die "16-at-a-time" - Einschränkung, die scheint Sie zu überraschen, ist eine ziemlich Natürliche.
Natürlich, ein sogenannter "counter" Rückkehr der gleichen Wert bei jedem Aufruf grob unsicher. Nicht viel besser zu machen, e.g....:
Secret('\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00').counter()
→OverflowError: unsigned byte integer is greater than maximum
.AES ist ein block cipher: es ist ein Algorithmus (genauer gesagt, ein paar algorithmen), nimmt einen Schlüssel und eine Nachricht blockieren und entweder verschlüsselt oder entschlüsselt den block. Die Größe eines Blocks ist immer 16 bytes, unabhängig von der Größe Schlüssel.
CTR ist ein Betriebsart. Es ist ein paar von algorithmen, baut auf einem block-Chiffre zu erzeugen, eine Stromchiffre, die verschlüsseln und entschlüsseln von Nachrichten beliebiger Länge.
CTR funktioniert durch die Kombination von aufeinander folgenden message blocks mit der Verschlüsselung von aufeinanderfolgenden Werten des Zählers. Die Größe des Zählers werden muss, um einen block, so dass es eine gültige Eingabe für die Blockchiffre.
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
. Aber wenn der key mehrfach verwendet, dann wird die zweite Nachricht nicht erneut verwenden darf jeder der counter-Werte verwendet, durch die erste Nachricht, und der einfachste Weg, um sicherzustellen, dass zum generieren der initial counter value-at-random (mit 2^128 Raum, die Chancen einer Kollision sind akzeptabel vernachlässigbar).Indem der Anrufer wählen Sie eine Zähler-Funktion, die PyCrypto-Bibliothek gibt Ihnen genug Seil an sich Aufhängen. Sollten Sie verwenden
Crypto.Util.Counter
, nicht nur "für bessere Leistung", wie die Dokumentation sagt, sondern weil es einfacher zu bauen ist etwas sicherer als das, was Sie wahrscheinlich zu kommen mit auf Ihrem eigenen. Und auch so, achten Sie auf einen zufälligen Anfangswert, das ist nicht der Standard.int_of_string(iv)
ersetzt werden kann, mitint.from_bytes(iv, byteorder='big')
in Python 3Ich kann definitiv zu spät und ich übersehen haben könnte die bisherigen Antworten, aber ich habe nicht eine klare Aussage, wie diese, sollte (zumindest IMHO) durchgeführt werden, entsprechend mit den PyCrypto-Pakete.
In Der Crypto.Util.Counter-Paket bietet callable stateful-Zähler, die sehr nützlich sind, aber es war einfach, zumindest für mich, Sie zu benutzen falsch.
Haben Sie einen Zähler erstellen, mit z.B.
ctr = Counter.new('parameters here')
. Jedes mal, wenn Ihr Zähler wird aufgerufen, durch Ihre counter-mode cipher-Objekt zum verschlüsseln der Nachricht, es wird erhöht. Dies ist nötig, um gute Kryptographie-Verfahren, da sonst Informationen, die etwa gleich große Blöcke können Auslaufen aus dem Chiffretext.Nun können Sie nicht an der Entschlüsselung-Funktion auf die gleichen cipher-Objekt, da es nennen würde, wieder den gleichen Zähler, der in der Zwischenzeit erhöht wurde, eventuell mehrmals. Was Sie tun müssen, ist erstellen Sie einen neuen cipher-Objekt mit einem anderen Zähler initialisiert mit den gleichen Parametern. Auf diese Weise ist die Entschlüsselung korrekt funktioniert, starten Sie den Zähler aus dem gleichen Punkt, wie die Verschlüsselung durchgeführt wurde.
Beispiel unten:
Es hat die gleiche Länge wie die cipher-block-Größe. CTR-Modus verschlüsselt die Theke und die XORs der Klartext mit dem verschlüsselten counter-Blocks.
Hinweise:
Standard-disclaimer: Crypto ist hart. Wenn Sie nicht verstehen, was Sie tun, Sie wird bekommen es falsch.
Verwenden scrypt. scrypt umfasst
encrypt
unddecrypt
die Verwendung von AES-CTR mit einem von einem Passwort abgeleiteten Schlüssel.Den Initialisierungsvektor ("counter") muss die gleiche bleiben, ebenso wie der Schlüssel ist, zwischen Verschlüsselung und Entschlüsselung. Es ist so, dass man codieren kann den gleichen text, eine million mal, und mit unterschiedlichen Chiffretext jeder Zeit (Prävention einige bekannt plaintext-Angriffe und pattern-matching /Angriffe). Sie immer noch auf dem selben IV entschlüsseln, wenn, wie beim verschlüsseln. In der Regel, wenn Sie starten Sie einen stream entschlüsseln initialisieren Sie die IV auf den gleichen Wert, mit dem Sie angefangen, als Sie anfingen, zu verschlüsseln, dass stream.
Sehen http://en.wikipedia.org/wiki/Initialization_vector für Informationen über die Initialisierung von Vektoren.
Beachten Sie, dass os.urandom(16) ist nicht "deterministisch", die eine Voraussetzung für die counter-Funktionen. Ich schlage vor, Sie verwenden die Inkrement-Funktion, wie das ist, wie CTR-Modus ausgelegt ist. Die ersten counter-Wert soll zufällig sein, aber die aufeinander folgenden Werte sollten vollständig vorhersagbar aus dem ersten Wert ("deterministisch"). Der erste Wert kann auch übernommen werden für Sie (ich weiß nicht die details)
Über den Schlüssel, IV, und input-Größen, es klingt wie der cipher, die Sie wählten, hat eine Blockgröße von 16 bytes. Alles, was Sie beschreiben, passt, und scheint mir normal zu sein.