2016-03-25 8 views
1

So habe ich ein Stück Code, der eine Zeichenfolge mit einer Passphrase verschlüsselt. Es nutzt die CryptoJS AES Verschlüsselungsfunktion (CryptoJS.AES.encrypt) und sieht wie folgt aus ...Entschlüsseln CryptoJS AES-Daten (mit Passphrase) in Forge.js

CryptoJS.AES.encrypt(data, password).toString(); 

Auch in Zukunft will ich nicht CryptoJS zu verwenden, wie es offiziell veraltet ist nicht gepflegt/und ich würde statt wie Forge.js zu verwenden. Ich habe versucht, die Forge.js-Dokumentation auf GitHub zu lesen, um eine Lösung zu finden, konnte aber nichts finden, das Passphrasen verwendet, anstatt den Schlüssel manuell zu erstellen. & IV.

ich einen Blick auf dem CryptoJS Archiv unter https://code.google.com/archive/p/crypto-js/ genommen habe und es scheint, dass, wenn die encrypt Funktion eine Zeichenfolge als das zweite Argument (key) übergeben wird es als Passwort verwendet wird, einen Schlüssel zu leiten und IV. Aber es ist nicht detailliert, wie es das macht.

Es scheint, dass Base64 Dekodierung das Ergebnis gibt eine Zeichenfolge, die mit Salted__ dann ein Komma und dann den verschlüsselten Blob von Binärtext beginnt, und ich bin mir nicht sicher, wie ich die "Salz" zu Forge übergeben würde.

Wie würde ich diesen Datenblob nur mit Forge.js entschlüsseln?

Antwort

4

CryptoJS unterstützt OpenSSLs EVP_BytesToKey-Funktion, die Schlüssel und IV aus einem frisch generierten Salz und Passwort mit einer Runde MD5 ableitet. Es ist ein Beispiel auf den forge documentation page:

in node.js Mit schmieden OpenSSL „enc“ Kommandozeilen-Tool (Hinweis zum Spiel: OpenSSL „enc“ verwendet ein Nicht-Standard-Dateiformat mit einem benutzerdefinierten Schlüssel Ableitungsfunktion und eine feste Iterationszahlcode von 1, die einige betrachten weniger sicher als Alternativen wie OpenPGP/GnuPG):

var forge = require('node-forge'); 
var fs = require('fs'); 

// openssl enc -des3 -in input.txt -out input.enc 
function encrypt(password) { 
    var input = fs.readFileSync('input.txt', {encoding: 'binary'}); 

    // 3DES key and IV sizes 
    var keySize = 24; 
    var ivSize = 8; 

    // get derived bytes 
    // Notes: 
    // 1. If using an alternative hash (eg: "-md sha1") pass 
    // "forge.md.sha1.create()" as the final parameter. 
    // 2. If using "-nosalt", set salt to null. 
    var salt = forge.random.getBytesSync(8); 
    // var md = forge.md.sha1.create(); // "-md sha1" 
    var derivedBytes = forge.pbe.opensslDeriveBytes(
    password, salt, keySize + ivSize/*, md*/); 
    var buffer = forge.util.createBuffer(derivedBytes); 
    var key = buffer.getBytes(keySize); 
    var iv = buffer.getBytes(ivSize); 

    var cipher = forge.cipher.createCipher('3DES-CBC', key); 
    cipher.start({iv: iv}); 
    cipher.update(forge.util.createBuffer(input, 'binary')); 
    cipher.finish(); 

    var output = forge.util.createBuffer(); 

    // if using a salt, prepend this to the output: 
    if(salt !== null) { 
    output.putBytes('Salted__'); // (add to match openssl tool output) 
    output.putBytes(salt); 
    } 
    output.putBuffer(cipher.output); 

    fs.writeFileSync('input.enc', output.getBytes(), {encoding: 'binary'}); 
} 

// openssl enc -d -des3 -in input.enc -out input.dec.txt 
function decrypt(password) { 
    var input = fs.readFileSync('input.enc', {encoding: 'binary'}); 

    // parse salt from input 
    input = forge.util.createBuffer(input, 'binary'); 
    // skip "Salted__" (if known to be present) 
    input.getBytes('Salted__'.length); 
    // read 8-byte salt 
    var salt = input.getBytes(8); 

    // Note: if using "-nosalt", skip above parsing and use 
    // var salt = null; 

    // 3DES key and IV sizes 
    var keySize = 24; 
    var ivSize = 8; 

    var derivedBytes = forge.pbe.opensslDeriveBytes(
    password, salt, keySize + ivSize); 
    var buffer = forge.util.createBuffer(derivedBytes); 
    var key = buffer.getBytes(keySize); 
    var iv = buffer.getBytes(ivSize); 

    var decipher = forge.cipher.createDecipher('3DES-CBC', key); 
    decipher.start({iv: iv}); 
    decipher.update(input); 
    var result = decipher.finish(); // check 'result' for true/false 

    fs.writeFileSync(
    'input.dec.txt', decipher.output.getBytes(), {encoding: 'binary'}); 
} 

Dieses Beispiel für Triple dES gezeigt wird, aber es funktioniert auf die gleiche Art und Weise zum AES. Sie müssen nur die ivSize zu 16 ändern.

+0

Ich schätze es, das ist sehr viel die Antwort auf meine Frage. Ich habe übersehen, dass ich das erwähnte 3DES-Beispiel mit AES wiederverwenden konnte. –

+0

Ich merke, dass ich nicht antwortete, nachdem ich Ihren Vorschlag ausprobiert hatte. Vielleicht verpasse ich etwas, aber das einfache Ändern von "3DES" zu "AES" und von "8" zu "16" für die "ivSize" ergibt nicht die gleichen Ergebnisse. Ich habe versucht herauszufinden, was das Problem sein könnte, da Schmiede sagt, dass es erfolgreich war, aber die Ausgabe ist komplett anders - also frage ich mich, ob es ein Problem mit der Codierung ist? Nicht so sicher. –

+0

Forge gibt folgenden String aus ... '1pÍ0¿UÚ @ G4WtCÕ5¸« ñZ¿} Á6 © _ͬiñýü¾¸iÔú®ð5ÕÆÉP¹ú) & nQOW »AMب3 {~ 5 = O! ¼ = W²Ò? [...] ' Wo, wie cryptojs gibt das folgende ... ' ----- BEGIN RSA PRIVATE KEY ----- MIIEowIBAAKCAQEAqSFulewpMjRBLhiiorbvWleD5I [...] ' Ich würde gerne diese markieren Als richtiger Kommentar, aber mit dem obigen Ausschnitt würde ich nicht wollen, dass irgendjemand anderes auf dieses Problem stößt. –