Несовместимость в шифровании java AES и расшифровке js узла

#javascript #java #node.js #encryption #aes

Вопрос:

Я выполняю шифрование и расшифровку с использованием алгоритма AES на java и узле js, код для них :-

Узел Js:

 //ENCRYPTION:   var CryptoJS = require('crypto-js');  var encryption_key = 'encryptionKey';   // Convert JSON to string  var data = JSON.stringify({  "id": "1",  "name": "Adam",  "age" : 32  });  var encrypted_data = CryptoJS.AES.encrypt(data, encryption_key).toString();   // Here is the final data  console.log(encrypted_data);  //DECRYPTION  var cipher_data = 'cipherDataToDecrypt';  var decrypted = CryptoJS.AES.decrypt(cipher_data, encryption_key).toString(CryptoJS.enc.Utf8);  console.log(decrypted); 

Java-код:

 static String secret = "encryptionKey";  public static String encrypt(String plain) throws Exception {  String result = null;    byte[] saltData = RandomUtils.nextBytes(8);   MessageDigest md5 = MessageDigest.getInstance("MD5");  final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes(StandardCharsets.UTF_8), md5);  SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");  IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);   Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");  aesCBC.init(Cipher.ENCRYPT_MODE, key, iv);  byte[] encrypted = aesCBC.doFinal(plain.getBytes(StandardCharsets.UTF_8));   byte[] random = RandomUtils.nextBytes(8);  byte[] output = new byte[saltData.length random.length encrypted.length];  int i = 0;  for(byte b1 : random){  output[i] = b1;  i  ;  }  for(byte b1 : saltData){  output[i] = b1;  i  ;  }  for(byte b1 : encrypted){  output[i] = b1;  i  ;  }   result = Base64.getEncoder().encodeToString(output);  return result;  }  public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {   int digestLength = md.getDigestLength();  int requiredLength = (keyLength   ivLength   digestLength - 1) / digestLength * digestLength;  byte[] generatedData = new byte[requiredLength];  int generatedLength = 0;   try {  md.reset();   // Repeat process until sufficient data has been generated  while (generatedLength lt; keyLength   ivLength) {   // Digest data (last digest if available, password data, salt if available)  if (generatedLength gt; 0)  md.update(generatedData, generatedLength - digestLength, digestLength);  md.update(password);  if (salt != null)  md.update(salt, 0, 8);  md.digest(generatedData, generatedLength, digestLength);   // additional rounds  for (int i = 1; i lt; iterations; i  ) {  md.update(generatedData, generatedLength, digestLength);  md.digest(generatedData, generatedLength, digestLength);  }   generatedLength  = digestLength;  }   // Copy key and IV into separate byte arrays  byte[][] result = new byte[2][];  result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);  if (ivLength gt; 0)  result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength   ivLength);   return result;   } catch (DigestException e) {  throw new RuntimeException(e);   } finally {  // Clean out temporary data  Arrays.fill(generatedData, (byte)0);  }  }  public static String decrypt(String cipherText) throws Exception {    byte[] cipherData = Base64.getDecoder().decode(cipherText);  byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);    MessageDigest md5 = MessageDigest.getInstance("MD5");  final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes(StandardCharsets.UTF_8), md5);  SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");  IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);   byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);  Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");  aesCBC.init(Cipher.DECRYPT_MODE, key, iv);  byte[] decryptedData = aesCBC.doFinal(encrypted);  String decryptedText = new String(decryptedData, StandardCharsets.UTF_8);  return decryptedText;  }   

Код java совместим с шифрованием и дешифрованием. И узел js также совместим с шифрованием и дешифрованием. Также, если вы шифруете в узле js, код java может быть расшифрован. Но проблема возникает, когда я шифрую на java и пытаюсь расшифровать в Node Js . Это дает

Вывод js узла:

 throw new Error('Malformed UTF-8 data');  

Есть ли что-то, что я здесь делаю неправильно, или есть какой-либо другой способ выполнить этот вид шифрования и дешифрования на java ? Пожалуйста, предложите. Заранее спасибо

Комментарии:

1. В коде Java есть кодирование/декодирование URL-адреса, но не в коде NodeJS.

2. Да, я добавил его по ошибке в java-код. Я отредактировал его, но он все еще не работает

3. В коде Java используйте byte[] random = "Salted__".getBytes(StandardCharsets.US_ASCII); (а также лучше измените имя переменной). Формат OpenSSL начинается с кодировки ASCII Salted__ , а не со случайной последовательности байтов.

4. Это действительно помогло мне. спасибо @Topaco