2016-07-13 12 views
1

Ich versuche, unter Java-Code in Nodejs zu konvertieren.javax.crypto.Cipher äquivalenter Code in Nodejs Crypto Javascript

public static String encrypt(String accessToken) throws Exception { 
     Cipher cipher = Cipher.getInstance("AES"); 
     String merchantKey = "11111111111111111111"; 
     String st = StringUtils.substring(merchantKey, 0, 16); 
     System.out.println(st); 
     Key secretKey = new SecretKeySpec(st.getBytes(), "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
     byte[] encryptedByte = cipher.doFinal(accessToken.getBytes()); 

     // convert the byte to hex format 
     StringBuffer sb = new StringBuffer(); 
     for (int i = 0; i < encryptedByte.length; i++) { 
      sb.append(Integer.toString((encryptedByte[i] & 0xff) + 0x100, 16).substring(1)); 
     } 
     return sb.toString(); 
    } 

Hier ist, was ich in der Lage war zu Figur out-

function freeChargeEncryptAES(token){ 
    var fcKey = "11111111111111111111".substring(0, 16); 
    var cipher = crypto.createCipher('aes-128-ecb', fcKey, ""); 
    var encrypted = cipher.update(token,'ascii','hex'); 
    encrypted += cipher.final('hex'); 
    return encrypted; 
} 

Ich bin nicht in der Lage gleiche Leistung zu erhalten. Zum Beispiel, wenn

token = "abcdefgh"

Java-Code-Ausgang - bc02de7c1270a352a98faa686f155df3

NodeJS-Code-Ausgang - eae7ec6943953aca94594641523c3c6d

Ich habe von this answer gelesen, dass Verschlüsselungsalgorithmus ist standardmäßig aes-ecb, die IV nicht benötigt. Da die Schlüssellänge 16 ist, gehe ich davon aus, dass aes-128-ecb (16 * 8 = 128) der Algorithmus ist, den ich verwenden sollte.

Kann mir jemand helfen, das Problem herauszufinden?

+0

** Verwenden Sie niemals [ECB-Modus] (http://crypto.stackexchange.com/q/14487/13022) **. Es ist deterministisch und daher nicht semantisch sicher. Sie sollten zumindest einen randomisierten Modus wie [CBC] (http://crypto.stackexchange.com/q/22260/13022) oder [CTR] verwenden (http://crypto.stackexchange.com/a/2378/ 13022). Es ist besser, Ihre Chiffriertexte zu authentifizieren, so dass Angriffe wie ein [padding oracle attack] (http://crypto.stackexchange.com/q/18185/13022) nicht möglich sind. Dies kann mit authentifizierten Modi wie GCM oder EAX oder mit einem [encrypt-then-MAC] (http://crypto.stackexchange.com/q/202/13022) Schema erfolgen. –

+0

Die IV muss unvorhersehbar sein (gelesen: zufällig). Verwenden Sie keine statische IV, da dies die Chiffre deterministisch und daher nicht semantisch sicher macht. Ein Angreifer, der Chiffriertexte beobachtet, kann feststellen, wann das gleiche Nachrichtenpräfix vorher gesendet wurde. Die IV ist nicht geheim, Sie können sie also zusammen mit dem Geheimtext senden. Normalerweise wird es einfach dem Geheimtext vorangestellt und vor der Entschlüsselung abgeschnitten. –

+0

@ArtjomB. Danke für die Info, aber mein Anwendungsfall ist anders. Ich möchte nur den obigen Java-Code in nodejs umwandeln. Die Java-Implementierung gibt den Algorithmus nicht an, aber der Oracle Java JCE-Provider verwendet standardmäßig ECB. –

Antwort

0

einfach ändern müssen -

crypto.createCipher('aes-128-ecb', fcKey, "");

zu

crypto.createCipheriv('aes-128-ecb', fcKey, "");

Grund ist einfach - createCipher Methode behandelt zweite Parameter ein s Encryption Password während es eine Encryption Key ist.

Meine schlechte, auch nach dem Lesen this answer, habe ich falsche Methode (crypto.createCipher statt crypto.createCipheriv) verwendet. Unten ist der korrekte Arbeitscode in nodejs. Das war alles nötig.

function freeChargeEncryptAES(token){ 
    var fcKey = "11111111111111111111".substring(0, 16); 
    var cipher = crypto.createCipheriv('aes-128-ecb', fcKey, ""); 
    var encrypted = cipher.update(token,'ascii','hex'); 
    encrypted += cipher.final('hex'); 
    return encrypted; 
} 
Verwandte Themen