Come decifrare un cryptojs AES messaggio al java lato server?

Ho il seguente cryptojs a base di javascript di crittografia/decrittografia funzioni che funziona perfettamente bene.

Io uso un casuale sale, casuale iv valore e una password specifica, mentre la crittografia del messaggio utilizzando cryptpjs. Io riutilizzare lo stesso sale, iv e la password per generare la chiave mentre decifrare il messaggio cifrato.

Questa parte funziona bene..

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);
} 

Ma il problema inizia quando cerco di decifrare lo stesso testo cifrato al java lato server.
Voglio che il messaggio cifrato per essere decifrati da java il codice del server.
Qui è il codice Java che ho scritto:

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;
}

Ma ottengo il seguente eccezione:

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)

Non ho idea di cosa dovrei fare

InformationsquelleAutor user1455719 | 2014-12-02



2 Replies
  1. 8

    Questa parte del codice è sbagliato:

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

    Il 128/32 valore è errato. È necessario 128, 192 o 256. Attualmente è l’equivalente di 4, che sembra derivare in nessun output dal PBKDF2 funzione.

    Anche, in Java si dovrebbe usare DatatypeConverter.parseHexBinary(), o simili, per la conversione hex in byte. Attualmente si sta appena chiamata getBytes() che non è giusto.

    Infine, è necessario specificare la modalità CBC e PKCS#5 imbottitura per abbinare il vostro codice Javascript. Quindi modificare la riga:

    Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
    • Il momento in cui ho fatto le modifiche che hai suggerito , ha funzionato . Grazie Duncan. Io ne garantiscono la completa soluzione di lavoro come un’altra risposta. Grazie cumuli. È sulla strada giusta e risolto i miei problemi.
  2. 9

    Grazie a Duncan per la pronta risposta e i consigli. Io sto dando la completa soluzione che ha funzionato per me, qui di seguito, a beneficio di altri.

    Il codice Java per fare la decifrazione dei cryptojs messaggio cifrato

    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;
    }
    • Ho usato il tuo codice Javascript (in questione) e il codice Java (in questa risposta) come esempio e l’ho messa in atto. Il codice Java è successo quando la password, sale, iv e crittografati sono hardcoded come fatto in questa risposta. Ho anche usato il tuo codice javascript lato client, ma sembra che non ci sia qualche errata configurazione in js lato come la dimensione della chiave e così via, coz di che sto diventando cattivo imbottitura eccezioni in java quando si decodifica il codice javascript dati codificati. Potete fornire il lavoro di codice javascript..
    • È “Dato Finale blocco non adeguatamente imbottito” errore java

Lascia un commento