Verschlüsseln und Entschlüsseln mit python und nodejs
Ich versuche zu verschlüsseln, einigen Inhalt in Python und entschlüsseln es in einer nodejs-Anwendung.
Ich bin kämpfen, um die zwei AES-Implementierungen arbeiten zusammen. Hier ist, wo ich bin.
In Knoten:
var crypto = require('crypto');
var password = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
var input = 'hello world';
var encrypt = function (input, password, callback) {
var m = crypto.createHash('md5');
m.update(password)
var key = m.digest('hex');
m = crypto.createHash('md5');
m.update(password + key)
var iv = m.digest('hex');
//add padding
while (input.length % 16 !== 0) {
input += ' ';
}
var data = new Buffer(input, 'utf8').toString('binary');
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
var encoded = new Buffer(encrypted, 'binary').toString('base64');
callback(encoded);
};
var decrypt = function (input, password, callback) {
//Convert urlsafe base64 to normal base64
var input = input.replace('-', '+').replace('/', '_');
//Convert from base64 to binary string
var edata = new Buffer(input, 'base64').toString('binary')
//Create key from password
var m = crypto.createHash('md5');
m.update(password)
var key = m.digest('hex');
//Create iv from password and key
m = crypto.createHash('md5');
m.update(password + key)
var iv = m.digest('hex');
//Decipher encrypted data
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv.slice(0,16));
var decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
var plaintext = new Buffer(decrypted, 'binary').toString('utf8');
callback(plaintext);
};
encrypt(input, password, function (encoded) {
console.log(encoded);
decrypt(encoded, password, function (output) {
console.log(output);
});
});
Dieses Beispiel erzeugt die Ausgabe:
BXSGjDAYKeXlaRXVVJGuREKTPiiXeam8W9e96Nknt3E=
hello world
In python
from Crypto.Cipher import AES
from hashlib import md5
import base64
password = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
input = 'hello world'
def _encrypt(data, nonce, password):
m = md5()
m.update(password)
key = m.hexdigest()
m = md5()
m.update(password + key)
iv = m.hexdigest()
# pad to 16 bytes
data = data + " " * (16 - len(data) % 16)
aes = AES.new(key, AES.MODE_CBC, iv[:16])
encrypted = aes.encrypt(data)
return base64.urlsafe_b64encode(encrypted)
def _decrypt(edata, nonce, password):
edata = base64.urlsafe_b64decode(edata)
m = md5()
m.update(password)
key = m.hexdigest()
m = md5()
m.update(password + key)
iv = m.hexdigest()
aes = AES.new(key, AES.MODE_CBC, iv[:16])
return aes.decrypt(edata)
output = _encrypt(input, "", password)
print(output)
plaintext = _decrypt(output, "", password)
print(plaintext)
Dieses Beispiel erzeugt die Ausgabe
BXSGjDAYKeXlaRXVVJGuRA==
hello world
Klar, Sie sind sehr nahe, aber Knoten scheint Polsterung die Ausgabe mit etwas. Irgendwelche Ideen, wie ich können die beiden zusammenarbeiten?
- 1) brauchst du wirklich Passwort-basierte Verschlüsselung, statt mit einem zufälligen Schlüssel? 2) Wenn Sie das tun, verwenden Sie nicht eine einzige iteration von hash-Funktionen. Verwenden Sie ein Salz, und slow-Taste-Ableitung Funktionen wie PBKDF2, bcrypt oder scrypt.
- 3) Sie nicht die IV richtig entweder. Es sollte eine neue, zufällige Wert für jede Nachricht. Es sollte auch die gleiche Größe wie die Blockgröße, und nicht die Hälfte der Blockgröße, wie in deinem Beispiel.
- Danke @CodeInChaos dies ist Beispielcode, damit ich vereinfacht einiges. Das Passwort wird erzeugt mit PBKDF2 und die IV randomisiert werden, in der Produktion.
Du musst angemeldet sein, um einen Kommentar abzugeben.
OK, ich habe es herausgefunden, Knoten verwendet OpenSSL verwendet PKCS5 zu tun-Polsterung. PyCrypto nicht handhaben, die Polsterung so war ich es selbst zu tun, fügen Sie einfach '' in beiden.
Wenn ich PKCS5 padding in der python-code, und entfernen Sie die Polsterung in den Knoten der code, es funktioniert.
So aktualisiert, funktionierenden code.
Knoten:
Python:
-
oder mehrere/
. Auch im entschlüsseln, die Sie ersetzen müssen_
mit/
, nicht die andere Weise herum. Sie können einfach ersetzen Sie diese Zeile mit:var input = input.replace(/\-/g, '+').replace(/_/g, '/');
var data = new Buffer(input, 'utf8').toString('binary');
man sollte nicht angeben, 'utf8' zu erstellenencrypted
aber halten Sie sich stattdessen mit 'binären'Nur für eine, die ähnlich ist zu mir, wer war auf der Suche nach einem einfachen Weg, um die Verschlüsselung und Entschlüsselung bei AES in python, das tun die gleiche Sache in node.js. Die Klasse hier unterstützt verschiedene bits des AES und die beiden hex-und base64-Kodierung erzeugt dasselbe Ergebnis in node.js.
Bemerkte auch, dass wenn Sie fehlen, das Paket Crypto, können Sie einfach installieren Sie es, indem
Den code für python ist wie folgt:
Im folgenden finden Sie Beispiele zur Verwendung der Klasse:
Verschlüsselung Beispiel:
Entschlüsselung Beispiel: