2017-09-14 1 views
1

Hallo Ich habe Nodejs-Verschlüsselung und Java-Verschlüsselung mit dem gleichen Algorithmus auf beiden Seiten geschrieben. Java und NodeJS geben jedoch unterschiedliche verschlüsselte Zeichenfolgen zurück. Bitte hilf mir hier.Nodejs Verschlüsselte Zeichenfolge, die nicht mit Java übereinstimmt: AES-256-CBC

// Hier ist mein Java-Code

import java.io.UnsupportedEncodingException; 
import java.security.Key; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.security.spec.AlgorithmParameterSpec; 

    import javax.crypto.Cipher; 
    import javax.crypto.spec.IvParameterSpec; 
    import javax.crypto.spec.SecretKeySpec; 
    import java.util.Base64; 

    public enum AESUtil { 
     ; 
     private static final String ENCRYPTION_KEY = "RwcmlVpg"; 
     private static final String ENCRYPTION_IV = "4e5Wa71fYoT7MFEX"; 

     public static String encrypt(String src) { 
      try { 
       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
       cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv()); 
       Base64.Encoder encoder = Base64.getEncoder(); 
       return encoder.encodeToString(cipher.doFinal(src.getBytes())); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 

     public static String decrypt(String src) { 
      String decrypted = ""; 
      try { 
       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
       cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv()); 
       Base64.Decoder decoder = Base64.getDecoder(); 
       decrypted = new String(cipher.doFinal(decoder.decode(src))); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
      return decrypted; 
     } 

     static AlgorithmParameterSpec makeIv() { 
      try { 
       return new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8")); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     static Key makeKey() { 
      try { 
       MessageDigest md = MessageDigest.getInstance("SHA-256"); 
       byte[] key = md.digest(ENCRYPTION_KEY.getBytes("UTF-8")); 
       return new SecretKeySpec(key, "AES"); 
      } catch (NoSuchAlgorithmException e) { 
       e.printStackTrace(); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 

      return null; 
     } 
    } 

// Unten ist der Code über den Code zu testen

public class AESMain { 

     /** 
     * @param args 
     */ 
     public static void main(String[] args) { 
      String src = "Hello,CryptWorld"; 
      String encrypted = AESUtil.encrypt(src); 
      String decrypted = AESUtil.decrypt(encrypted); 
      System.out.println("src: " + src); 
      System.out.println("encrypted: " + encrypted); 
      System.out.println("decrypted: " + decrypted); 
     } 

    } 

Antwort aus dem obigen Code wird

src: Hello,CryptWorld 
encrypted: rh7ro9NH1XZeLX95paLETDgYxRbnDoOIrxarO0Sy73s= 
decrypted: Hello,CryptWorld 

// Knoten JS-Code

var Encrypt, crypto; 

crypto = require("crypto"); 


Encrypt = module.exports = (function() { 
    var b64dec, b64enc, cipher, decrypt, encrypt, iv, key; 
    key = crypto.createHash("sha256").update("RwcmlVpg").digest(); 
    iv = '4e5Wa71fYoT7MFEX'; 
    cipher = function(mode, data) { 
    var encipher, encoded; 
    encipher = crypto[mode]("aes-256-cbc", key, iv); 
    encoded = encipher.update(data); 
    encoded += encipher.final(); 
    return encoded; 
    }; 
    encrypt = function(data) { 
    return b64enc(cipher("createCipheriv", data)); 
    }; 
    decrypt = function(data) { 
    return cipher("createDecipheriv", b64dec(data)); 
    }; 
    b64enc = function(data) { 
    var b; 
    b = new Buffer(data, "binary"); 
    return b.toString("base64"); 
    }; 
    b64dec = function(data) { 
    var b; 
    b = new Buffer(data, "base64"); 
    return b.toString("binary"); 
    }; 
    return { 
    encrypt: encrypt, 
    decrypt: decrypt 
    }; 
})(); 
var expected = Encrypt.encrypt("Hello,CryptWorld"); 
console.log("expected " + expected); 

Die Antwort von Knoten JS ist

expected /R79/f1H/XZeLX95/f39TDgY/Rb9Dv39/Rb9O0T9/Xs= 

der Knoten js Version v6.10.1 und JDK Version 1.8.0_77 ist.

Ich weiß wirklich nicht, was ich vermisse.

Antwort

0

Ich bin kein Javascript oder node.js Experte, aber ich denke, das Problem ist, dass die cipher.update() und cipher.final() Instanzen von Buffer, nicht String zurückgeben. Daher müssen Sie Buffer.concat(...), um sie zu verketten, das heißt

cipher = function (mode, data) { 
    var encipher, encoded; 
    encipher = crypto[mode]("aes-256-cbc", key, iv); 
    cipher1 = encipher.update(data); 
    cipher2 = encipher.final(); 
    return Buffer.concat([cipher1, cipher2]); 
}; 

Darüber hinaus sollten Sie nie diese String.getBytes() Methode verwenden noch dieses String(byte[]) Konstruktor in jedem Code, der Portabilität oder Interoperabilität zu erreichen strebt. Geben Sie stattdessen den Zeichensatz immer explizit an. Ich würde UTF_8 ausschließlich empfehlen, z. Verwenden Sie also String.getBytes(StandardCharsets.UTF_8) und new String(byte[], StandardCharsets.UTF_8).

+0

Sie haben Recht, dies half bei der Lösung des Problems. –

0

Mein erster Tipp wäre, um sicherzustellen, dass Sie genau die gleichen:

  1. Zeichencodierung
  2. Zeilenenden

in Ihre beiden Programme für den Text verschlüsselt und für die Schlüssel. Versuchen Sie, die Textpuffer und Schlüssel als Hex auszudrucken und vergleichen Sie diese, bevor Sie überhaupt eine Verschlüsselung durchführen. Wenn sie sich unterscheiden, dann gibt es dein Problem. Wenn sie gleich sind, kann es ein Problem mit der Verschlüsselung selbst sein.

Beachten Sie, dass Knoten UTF-8 standardmäßig verwendet, während Java intern UCS-2 verwendet, soweit ich weiß. Ich sehe, Sie machen einige Versuche, die Codierung zu konvertieren, aber überprüfen Sie die Ergebnisse in beiden Anforderungen für Bot die Schlüssel und den Klartext kurz vor dem Verschlüsselungsschritt.

Stellen Sie außerdem sicher, dass Sie nicht die base64-Darstellung der Zeichenfolge anstelle der Zeichenfolge selbst verschlüsseln oder dass Sie konsistent sind, wenn Sie base64 für den Schlüssel verwenden.

Drucken Sie auch beide Schlüssel vor der Verschlüsselung. Sie bauen sie programmatisch auf, also stellen Sie sicher, dass Sie wissen, was sie am Ende sind.

und vergleichen Sie richtig die Arbeit, die von Ihrem Programm der Fall ist.

+0

Ihre Antwort schlägt vor, dass Sie den Code nicht wirklich angeschaut haben. –

+0

Danke für Ihre Hilfe. Ihr Vorschlag half beim Aufspüren des Problems. –

Verwandte Themen