Wie kann ich etwas mit Pycrypto entschlüsseln, das mit OpenSSL verschlüsselt wurde?

StackOverflow https://stackoverflow.com/questions/8806481

  •  26-10-2019
  •  | 
  •  

Frage

Ich habe mehrere Saiten, die mit OpenSSL verschlüsselt wurden. Zum Beispiel:

$ echo "original string" | openssl aes-256-cbc -p -a -pass pass:secret
salt=B898FE40EC8155FD
key=4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C
iv =EFA6105F30F6C462B3D135725A6E1618
U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy

Ich möchte diese Dinge mit Python entschlüsseln. Ich versuche, Pycrypto zu verwenden. Hier ist ein Exmaple -Skript mit den oben genannten Daten:

from base64 import b64decode, b64encode
from hashlib import md5
from Crypto.Cipher import AES

secret = 'secret'
encoded = 'U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy'
encrypted = b64decode(encoded)
salt = encrypted[8:16]
data = encrypted[16:]
key = md5(secret + salt).hexdigest()
iv = md5(key + secret + salt).hexdigest()[0:16] # which 16 bytes?
dec = AES.new(key, AES.MODE_CBC, iv)
clear = dec.decrypt(data)

try:
    salt_hex = ''.join(["%X" % ord(c) for c in salt])
    print 'salt:     %s' % salt_hex
    print 'expected: %s' % 'B898FE40EC8155FD'
    print 'key:      %s' % key.upper()
    print 'expected: %s' % '4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C'
    print 'iv:       %s' % iv
    print 'expected: %s' % 'EFA6105F30F6C462B3D135725A6E1618'
    print 'result: %s' % clear
except UnicodeDecodeError:
    print 'decryption failed'

Hier ist die Ausgabe:

salt:     B898FE40EC8155FD
expected: B898FE40EC8155FD
key:      4899E518743EB0584B0811AE559ED8AD
expected: 4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C
iv:       17988376b72f4a81
expected: EFA6105F30F6C462B3D135725A6E1618
decryption failed

Sie können sehen, dass das Salz übereinstimmt und der Schlüssel der ersten Hälfte dessen entspricht, was OpenSSL zeigt. Daher habe ich auf dem richtigen Weg, aber es gibt zwei Hauptfragen:

  1. Warum sind die Werte für key und iv von OpenSSL doppelt so lang wie Pycrypto (und vermutlich AES256)?
  2. Wie generiere ich die richtigen Werte? Die Technik, die ich verwende ein Blog, Aber wenn die IV immer mit der Blockgröße (16 Bytes) übereinstimmen soll, wird MD5 niemals funktionieren. Und selbst wenn ich herausfinden könnte, woher die andere Hälfte des Schlüssel kommt, würde Pycrypto es ablehnen, zu lange zu sein.

Mir ist klar, dass ich auch die Polsterung entfernen muss, aber ich habe das für Kürze ausgelassen.

War es hilfreich?

Lösung

Sie haben drei Probleme:

  1. Sie verwenden AES256 (32 Byte -Schlüssel) in OpenSSL und AES128 (16 Byte -Schlüssel) in Ihrem Python -Code.
  2. Die IV -Berechnung ist falsch. Jeder Schritt in der wichtigsten Ableitung der OpenSSL verwendet den letzten MD5 Digest, der zuletzt berechnet wurde.
  3. Sie mischen eine binäre und hexadezimale Darstellung. Behalten Sie die Konvertierung in Hexadezimal als letzter Schritt vor der Visualisierung bei.

Der folgende Code sollte korrekt sein:

from base64 import b64decode, b64encode
from binascii import hexlify
from Crypto.Cipher import AES
from Crypto.Hash import MD5

secret = 'secret'
encoded = 'U2FsdGVkX1+4mP5A7IFV/VcgRs4ci/yupMErHjf5bkT5XrcowXK7z3VyyV1l2jvy'
encrypted = b64decode(encoded)
salt = encrypted[8:16]
data = encrypted[16:]

# We need 32 bytes for the AES key, and 16 bytes for the IV
def openssl_kdf(req):
    prev = ''
    while req>0:
        prev = MD5.new(prev+secret+salt).digest()
        req -= 16
        yield prev
mat = ''.join([ x for x in openssl_kdf(32+16) ])
key = mat[0:32]
iv  = mat[32:48]

dec = AES.new(key, AES.MODE_CBC, iv)
clear = dec.decrypt(data)

try:
    salt_hex = ''.join(["%X" % ord(c) for c in salt])
    print 'salt:     %s' % salt_hex
    print 'expected: %s' % 'B898FE40EC8155FD'
    print 'key:      %s' % hexlify(key).upper()
    print 'expected: %s' % '4899E518743EB0584B0811AE559ED8AD9F0B5FA31B0B998FEB8453B8E3A7B36C'
    print 'iv:       %s' % hexlify(iv).upper()
    print 'expected: %s' % 'EFA6105F30F6C462B3D135725A6E1618'
    print 'result:   %s' % clear
except UnicodeDecodeError:
    print 'decryption failed'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top