2016-04-21 12 views
7

ich ein Passwort haben, das Verschlüsseln von JavaScript ist überWie das Passwort von JavaScript CryptoJS.AES.encrypt (Passwort, Passwort) in Python zu entschlüsseln

var password = 'sample' 
    var passphrase ='sample_passphrase' 
    CryptoJS.AES.encrypt(password, passphrase) 

Dann habe ich versucht, kommt das Passwort zu entschlüsseln, die von JavaScript in Python :

from Crypto.Cipher import AES 
    import base64 

    PADDING = '\0' 

    pad_it = lambda s: s+(16 - len(s)%16)*PADDING 
    key = 'sample_passphrase' 
    iv='11.0.0.101'  #------> here is my question, how can I get this iv to restore password, what should I put here? 
    key=pad_it(key)  #------> should I add padding to keys and iv? 
    iv=pad_it(iv)   ## 
    source = 'sample' 
    generator = AES.new(key, AES.MODE_CFB,iv) 
    crypt = generator.encrypt(pad_it(source)) 
    cryptedStr = base64.b64encode(crypt) 
    print cryptedStr 
    generator = AES.new(key, AES.MODE_CBC,iv) 
    recovery = generator.decrypt(crypt) 
    print recovery.rstrip(PADDING) 

I von Browser-Konsole JS überprüft, zeigt es, in CryptoJS.AES.encrypt(password, passphrase) IV mit einigen Attributen ein Objekt (wie sigBytes:16, words: [-44073646, -1300128421, 1939444916, 881316061]). Es scheint zufällig erzeugt zu werden.

Von einer Seite, es sagt mir, dass JS Zweiweg Passwort zu verschlüsseln hat (reference link):

  • ein. crypto.createCipher(algorithm, password)
  • b. crypto.createCipheriv(algorithm, key, iv)

Was ich in JavaScript gesehen sollte eine Option sein. Allerdings entspricht nur Option b AES.new() in Python.

Die Fragen sind:

  1. Wie kann ich das Passwort in Python wiederherstellen, ohne JavaScript-Code zu ändern?

  2. Wenn ich IV in Python brauche, wie bekomme ich es aus dem Passwort, das in JavaScript verwendet wird?

+0

CryptoJS AES verwendet standardmäßig den CBC-Modus, so dass kein CBF-Modus in Python benötigt wird. AES.encrypt gibt auch ein Objekt zurück. Mit toString() erhalten Sie einen base64-kodierten Blob, der salt, iv und message enthält. Alle von ihnen müssen Sie Ende-Feed in Python trennen. Beachten Sie auch, dass Passwort und Schlüssel zwei verschiedene Dinge sind. – SKR

+0

Danke, ändern Sie einfach Schlüssel zu sample_passphrase, damit es klarer wird. aber was ist, wenn ich nicht zur String() Ausgabe komme? Ist das ein unmöglicher Job? @SKR – Bing

+0

Also meinst du, du hast überhaupt keine Kontrolle über die js? Wie geht der JS-Code weiter? Was passiert mit dem Objekt, das von encrypt zurückgegeben wird? Sie müssen das Salz und iv aus dem js irgendwie bekommen. Oder willst du nur das Verhalten der js "verspotten" und eine ähnliche verschlüsselte Nachricht für eine externe API oder etwas generieren? – SKR

Antwort

10

Sie müssen OpenSSL implementieren EVP_BytesToKey, denn das ist, was CryptoJS verwendet den Schlüssel und IV aus dem bereitgestellten Kennwort abzuleiten, aber PyCrypto unterstützt nur den Schlüssel + IV-Typ-Verschlüsselung. CryptoJS generiert auch ein zufälliges Salz, das ebenfalls an den Server gesendet werden muss. Wenn das Chiffretextobjekt in eine Zeichenfolge konvertiert wird, verwendet es automatisch ein OpenSSL-kompatibles Format, das das zufällige Salz enthält.

var data = "Some semi-long text for testing"; 
 
var password = "some password"; 
 
var ctObj = CryptoJS.AES.encrypt(data, password); 
 
var ctStr = ctObj.toString(); 
 

 
out.innerHTML = ctStr;
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script> 
 
<div id="out"></div>

möglicher Ausgang:

U2FsdGVkX1 + ATH716DgsfPGjzmvhr + 7 + pzYfUzR + 25u0D7Z5Lw04IJ + LmvPXJMpz

CryptoJS standardmäßig auf 256-Bit-Schlüsselgröße für AES, PKCS # 7 Padding und CBC-Modus. AES hat eine 128-Bit-Blockgröße, die auch die IV-Größe ist. Dies bedeutet, dass wir von EVP_BytesToKey 32 + 16 = 48 Byte anfordern müssen. Ich habe eine semi-funktionale Implementierung here gefunden und weiter ausgebaut.

Hier ist das vollständige Python (getestet mit 2.7 und 3.4) Code, der mit CryptoJS kompatibel:

from Crypto import Random 
from Crypto.Cipher import AES 
import base64 
from hashlib import md5 

BLOCK_SIZE = 16 

def pad(data): 
    length = BLOCK_SIZE - (len(data) % BLOCK_SIZE) 
    return data + (chr(length)*length).encode() 

def unpad(data): 
    return data[:-(data[-1] if type(data[-1]) == int else ord(data[-1]))] 

def bytes_to_key(data, salt, output=48): 
    # extended from https://gist.github.com/gsakkis/4546068 
    assert len(salt) == 8, len(salt) 
    data += salt 
    key = md5(data).digest() 
    final_key = key 
    while len(final_key) < output: 
     key = md5(key + data).digest() 
     final_key += key 
    return final_key[:output] 

def encrypt(message, passphrase): 
    salt = Random.new().read(8) 
    key_iv = bytes_to_key(passphrase, salt, 32+16) 
    key = key_iv[:32] 
    iv = key_iv[32:] 
    aes = AES.new(key, AES.MODE_CBC, iv) 
    return base64.b64encode(b"Salted__" + salt + aes.encrypt(pad(message))) 

def decrypt(encrypted, passphrase): 
    encrypted = base64.b64decode(encrypted) 
    assert encrypted[0:8] == b"Salted__" 
    salt = encrypted[8:16] 
    key_iv = bytes_to_key(passphrase, salt, 32+16) 
    key = key_iv[:32] 
    iv = key_iv[32:] 
    aes = AES.new(key, AES.MODE_CBC, iv) 
    return unpad(aes.decrypt(encrypted[16:])) 


password = "some password".encode() 
ct_b64 = "U2FsdGVkX1+ATH716DgsfPGjzmvhr+7+pzYfUzR+25u0D7Z5Lw04IJ+LmvPXJMpz" 

pt = decrypt(ct_b64, password) 
print("pt", pt) 

print("pt", decrypt(encrypt(pt, password), password)) 

ähnlicher Code kann in meinen Antworten für Java und PHP finden.

JavaScript AES-Verschlüsselung im Browser ohne HTTPS ist eine einfache Verschleierung und bietet keine echte Sicherheit, da der Schlüssel neben dem Chiffretext übertragen werden muss.

+0

Habe diesen versucht, es funktioniert einwandfrei. Danke vielmals. Ich weiß nicht viel darüber, wie das Verschlüsseln und Entschlüsseln mit diesen Optionen funktioniert. Wenn Sie einige Referenzlinks markieren könnten, die ich bekommen kann, werden diese Informationen sehr geschätzt. – Bing

+0

Ich bin mir nicht sicher, ob ich verstehe, nach welchen Referenzen Sie suchen. Wenn Sie darüber sprechen, wie ich das alles weiß, dann wäre der einfachste Weg, einfach den unminifizierten Quellcode zu nehmen und ihn zu lesen. –

+0

Ja, ich meine, wie man diese Informationen bekommt. Ich werde einen Code überprüfen. Vielen Dank. – Bing

Verwandte Themen