How to decrypt a cryptojs AES encrypted message at the java server side?

后端 未结 2 593
失恋的感觉
失恋的感觉 2021-02-08 12:02

I have the following cryptojs based javascript encryption/decryption functions which works perfectly fine.

I use a random salt, random iv value and a specific password

相关标签:
2条回答
  • 2021-02-08 12:37

    Thanks to Duncan for the prompt response and advice. I am giving the complete solution that worked for me below for the benefit of others.

    Java code to do the decryption of the cryptojs encrypted message

    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 讨论(0)
  • 2021-02-08 12:42

    This part of your code is wrong:

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

    The 128/32 value is erroneous. You need either 128, 192 or 256. Currently you have the equivalent of 4, which seems to result in no output at all from the PBKDF2 function.

    Also, in Java you should use DatatypeConverter.parseHexBinary(), or similar, to convert hex into bytes. Currently you are just calling getBytes() which isn't right.

    Finally, you need to specify CBC mode and PKCS#5 padding in order to match your Javascript code. So change the line to:

    Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
    
    0 讨论(0)
提交回复
热议问题