2014-12-02 6 views
7

Ich habe die folgenden cryptojs basierte Javascript-Verschlüsselung/Entschlüsselung Funktionen, die völlig in Ordnung funktioniert.Wie entschlüsselt man eine kryptojs AES-verschlüsselte Nachricht auf der Java-Server-Seite?

Ich benutze eine zufällige Salz, zufällige iv-Wert und ein bestimmtes Passwort beim Verschlüsseln der Nachricht mit cryptpjs. Ich benutze das gleiche Salz, iv und das Passwort, um den Schlüssel zu generieren, während ich die verschlüsselte Nachricht entschlüssle.

Dieser Teil funktioniert gut ..

function encrypt(){ 
    var salt = CryptoJS.lib.WordArray.random(128/8); 
    var iv = CryptoJS.lib.WordArray.random(128/8); 
    console.log('salt '+ salt); 
    console.log('iv '+ iv); 
    var key128Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 }); 
    console.log('key128Bits '+ key128Bits); 
    var key128Bits100Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 }); 
    console.log('key128Bits100Iterations '+ key128Bits100Iterations); 
    var encrypted = CryptoJS.AES.encrypt("Message", key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); 
    console.log('encrypted '+ encrypted ); 
} 

function decrypt(){ 
    var salt = CryptoJS.enc.Hex.parse("4acfedc7dc72a9003a0dd721d7642bde"); 
    var iv = CryptoJS.enc.Hex.parse("69135769514102d0eded589ff874cacd"); 
    var encrypted = "PU7jfTmkyvD71ZtISKFcUQ=="; 
    console.log('salt '+ salt); 
    console.log('iv '+ iv); 
    var key = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 }); 
    console.log('key '+ key); 
    var decrypt = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); 
    var ddd = decrypt.toString(CryptoJS.enc.Utf8); 
    console.log('ddd '+ddd); 
} 

Aber das Problem beginnt, wenn ich versuche, den gleichen verschlüsselten Text an der Java-Server-Seite zu entschlüsseln. Ich möchte, dass die verschlüsselte Nachricht von meinem Java-Server-Code entschlüsselt wird. Hier ist die Java-Code, den ich schrieb:

public static void main(String args[]) throws Exception{ 
    String password = "Secret Passphrase"; 
    String salt = "4acfedc7dc72a9003a0dd721d7642bde"; 
    String iv = "69135769514102d0eded589ff874cacd"; 
    String encrypted = "PU7jfTmkyvD71ZtISKFcUQ=="; 
    byte[] saltBytes = salt.getBytes(); //hexStringToByteArray(salt); 
    byte[] ivBytes = iv.getBytes();//hexStringToByteArray(iv); 
    IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);   
    SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes); 
    System.out.println(decrypt(encrypted , sKey ,ivParameterSpec)); 
} 

public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException { 

    KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32); 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    SecretKey secretKey = keyFactory.generateSecret(keySpec); 
    return new SecretKeySpec(secretKey.getEncoded(), "AES"); 
} 

public static String decrypt(String encryptedData, SecretKeySpec sKey, IvParameterSpec ivParameterSpec) throws Exception { 

    Cipher c = Cipher.getInstance("AES"); 
    c.init(Cipher.DECRYPT_MODE, sKey, ivParameterSpec); 
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

Aber ich bekomme die folgende Ausnahme:

Exception breakpoint: SecretKeySpec.java:96, java.lang.IllegalArgumentException, Empty key 
Exception in thread "main" java.lang.IllegalArgumentException: Empty key 
at javax.crypto.spec.SecretKeySpec.<init>(SecretKeySpec.java:96) 

Ich habe keine Ahnung, was ich

Antwort

7

Dieser Teil des Codes tun sollten, ist falsch :

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32); 
//->---------------------------------------------------------------------^^^^^^^ 

Der 128/32 Wert ist fehlerhaft. Sie benötigen entweder 128, 192 oder 256. Gegenwärtig haben Sie das Äquivalent von 4, was zu keinerlei Ausgabe von der PBKDF2-Funktion zu führen scheint.

In Java sollten Sie auch DatatypeConverter.parseHexBinary() o.ä. verwenden, um hex in Bytes zu konvertieren. Momentan rufen Sie gerade getBytes() an, was nicht richtig ist.

Schließlich müssen Sie CBC-Modus und PKCS # 5 Auffüllen angeben, um Ihren Javascript-Code zu entsprechen. Ändern Sie die Zeile daher wie folgt:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
+1

In dem Moment zu tun Sie vorgeschlagen, es funktionierte. Danke Duncan. Ich werde die komplette Arbeitslösung als eine andere Antwort liefern. Tausend Dank. Sie waren genau richtig und haben meine Probleme behoben. – user1455719

6

Danke an Duncan für die schnelle Antwort und Beratung. Ich gebe die komplette Lösung, die für mich funktionierte, zum Wohle anderer.

Java Code, um die Entschlüsselung der verschlüsselten Nachricht cryptojs i die Änderungen haben

public static void main(String args[]) throws Exception{ 

String password = "Secret Passphrase"; 
String salt = "222f51f42e744981cf7ce4240eeffc3a"; 
String iv = "2b69947b95f3a4bb422d1475b7dc90ea"; 
String encrypted = "CQVXTPM2ecOuZk+9Oy7OyGJ1M6d9rW2D/00Bzn9lkkehNra65nRZUkiCgA3qlpzL"; 

byte[] saltBytes = hexStringToByteArray(salt); 
byte[] ivBytes = hexStringToByteArray(iv); 
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);   
SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes); 
System.out.println(decrypt(encrypted , sKey ,ivParameterSpec)); 

} 

public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException { 

KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128); 
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
SecretKey secretKey = keyFactory.generateSecret(keySpec); 

return new SecretKeySpec(secretKey.getEncoded(), "AES"); 
} 

public static byte[] hexStringToByteArray(String s) { 

int len = s.length(); 
byte[] data = new byte[len/2]; 

for (int i = 0; i < len; i += 2) { 
    data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
    + Character.digit(s.charAt(i+1), 16)); 
} 

    return data; 

} 

public static String decrypt(String encryptedData, SecretKeySpec sKey, IvParameterSpec ivParameterSpec) throws Exception { 

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
c.init(Cipher.DECRYPT_MODE, sKey, ivParameterSpec); 
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
byte[] decValue = c.doFinal(decordedValue); 
String decryptedValue = new String(decValue); 

return decryptedValue; 
} 
+0

Ich habe Ihren Javascript-Code (in Frage) und Java-Code (in dieser Antwort) als Beispiel verwendet und ich habe es implementiert. Java-Code funktioniert erfolgreich, wenn das Passwort, salt, iv und chiffriert wie in dieser Antwort fest codiert ist. Ich habe auch Ihren JavaScript-Code für Client-Seite verwendet, aber es scheint, dass es einige Fehlkonfigurationen in der js-Seite wie Schlüsselgröße und so weiter gibt, denn ich bekomme schlechte Padding-Ausnahme in Java beim Decodieren der Javascript-codierten Daten. Können Sie den Arbeits Javascript-Code zur Verfügung stellen. –

+0

Es ist "gegebener abschließender Block nicht richtig gepolstert" Fehler in Java –

Verwandte Themen