2016-10-26 11 views
2

Ich habe älteren Verschlüsselungscode in C# und jetzt muss ich die gleiche Verschlüsselung in JavaScript durchführen. Ich habe etwas recherchiert und 3 verschiedene Bibliotheken ausprobiert, konnte jedoch nicht die gleichen Ergebnisse erzielen. Letzte Bibliothek, die ich benutzt habe, ist CryptoJS und ich muss herausfinden, warum ich unterschiedliche Ergebnisse bekomme.C# & JS-Verschlüsselungsmethoden geben unterschiedliche Ergebnisse zurück

Hier sind beide Code-Schnipsel:

C# -Code:

text = "chocolate"; 

    PasswordHash = "hashhash"; 
    SaltKey = "saltsaltsaltsa"; 
    VIKey = "iviviviviviviviv"; 

    byte[] plainTextBytes = Encoding.UTF8.GetBytes(text); 

    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256/8); 
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros }; 
    var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey)); 

    byte[] cipherTextBytes; 

    using (var memoryStream = new MemoryStream()) 
    { 
     using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) 
     { 
     cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
     cryptoStream.FlushFinalBlock(); 
     cipherTextBytes = memoryStream.ToArray(); 
     cryptoStream.Close(); 
     } 
     memoryStream.Close(); 
    } 
    var result = Convert.ToBase64String(cipherTextBytes); 

Ergebnis ==> "8AbNsyyqHHfi/PEF/bbiew =="

JavaScript-Code:

pass = 'chocolate'; 
//Creating the Vector Key 
var iv = CryptoJS.enc.Utf8.parse('iviviviviviviviv'); 
//Encoding the Password in from UTF8 to byte array 
var passHash = CryptoJS.enc.Utf8.parse('hashhash'); 
//Encoding the Salt in from UTF8 to byte array 
var Salt = CryptoJS.enc.Utf8.parse("saltsaltsaltsa"); 

//Creating the key in PBKDF2 format to be used during the encryption 
var key128Bits1000Iterations = CryptoJS.PBKDF2(passHash, Salt, { keySize: 256/8, iterations: 1000 }); 

//Encrypting the string contained in cipherParams using the PBKDF2 key 
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(pass), key128Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv, padding: CryptoJS.pad.ZeroPadding }); 
var result = encrypted.ciphertext.toString(CryptoJS.enc.Base64); 

Ergebnis = "dpgTA41PD yrM8ef9C1c8iA == "

+0

Sie scheinen mit 'Encoding.ASCII' in C# werden und 'CryptoJS.enc.Utf8' in der JS ..? – stuartd

+0

@stuartd - dachte darüber nach, dasselbe Verhalten für sowohl ASCII als auch UTF8 im gegebenen Szenario – Niro

Antwort

0

Endlich eine Lösung bekommen. Danke an Luke Park, der mir gesagt hat, dass CryptoJS eine 4-Byte (Wort) -Struktur verwendet.

Das Problem, das zu anderen Ergebnissen führte, ist, dass die Schlüsselgröße (anscheinend) unterschiedlich ist. In C# 256/8 ist eigentlich 32 Bytes Länge, aber in CryptoJS, da 4 Bytes verwenden, übersetzt 256/8 praktisch auf 128 Bytes Länge :(

Sobald ich die Schlüsselgröße im JS-Snippet auf 256/ändern 32 ((256/32) * 4 = 32) es funktioniert perfekt und gleiche Ergebnisse wie die C# Verschlüsselungsmethode echo.

Vielen Dank an all Nir

0

Das Problem ist mit Ihren PBKDF2-Salzen. CryptoJS verwendet eine WordArray als das Primitiv zum Speichern von Salzen. Das ist ein Array von 32-Bit-Werten. Wo als C# 8-Bit-Werte verwendet (offensichtlich ist es ein byte Array).

Hinweis dann, dass in JS:

var Salt = CryptoJS.lib.WordArray.create([1, 2]); 

ist, in C#, das gleiche wie:

byte[] Salt = new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 }; 

Sie können dies zeigen, indem sie die folgenden in JS ausgibt:

var Salt = CryptoJS.lib.WordArray.create([1, 2]); 
console.log(Salt.toString(CryptoJS.enc.Base64)); 
-> AAAAAQAAAAI= 

CryptoJS mag keine Saiten, die als Salze verwendet werden können. Es mag es überhaupt nicht. Sie sollten sowieso keine Zeichenfolge oder Phrase als Salz verwenden, sie sollte zufällig generiert und neben dem Passwort-Hash gespeichert werden.

+0

Das ist genau das, was" CryptoJS.enc.Utf8.parse "macht: Konvertiere String in seine Wortreihenrepräsentation – Niro

+0

Ja, also ist das Salz in C# vs JS anders. –

+0

Da liegst du falsch, die Salze sind gleich. Einer wird mit Bytes und der andere mit Worten dargestellt, aber die Daten sind genau gleich. Allerdings - du hast mir eine Anleitung gegeben, die mich zu einer Lösung geführt hat, also danke trotzdem :) – Niro

Verwandte Themen