#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 начинается с кодировки ASCIISalted__
, а не со случайной последовательности байтов.4. Это действительно помогло мне. спасибо @Topaco