Зашифруйте строку в nodejs и расшифруйте в java
Я шифрую текст в NODEJS и пытаюсь расшифровать в Java, но получаю ошибку. мой код nodejs:
var crypto = require('crypto')
, key = 'mykey@91'
, plaintext = 'SS18617710213463'
, cipher = crypto.createCipher('aes-128-ecb', key)
, decipher = crypto.createDecipher('aes-128-ecb', key);
var encryptedPassword = cipher.update(plaintext, 'utf8', 'base64');
encryptedPassword += cipher.final('base64')
var decryptedPassword = decipher.update(encryptedPassword, 'base64', 'utf8');
decryptedPassword += decipher.final('utf8');
console.log('original :', plaintext);
console.log('encrypted :', encryptedPassword);
console.log('decrypted :', decryptedPassword);
но когда я пытаюсь расшифровать его, он всегда выдает ошибку.
public static String decrypt(String encryptedText) {
try {
final String key = "mykey@91";
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] cipherText = Base64.getDecoder().decode(encryptedText.getBytes("UTF8"));
String decryptedString = new String(cipher.doFinal(cipherText),"UTF8");
return decryptedString;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Ошибка, которую я получаю, как показано ниже:
java.security.InvalidKeyException: неверная длина ключа AES: 8 байт
1 ответ
Причина, по которой вы получаете Invalid AES key length: 8 bytes invalid AES
связано с длиной вашего ключа и текста. Вы должны убедиться, что его длина в битах является степенью двойки. Если вы хотите использовать String в качестве ключа шифрования, проверьте его длину в байтах и умножьте на 8, чтобы найти длину в битах. Также для большинства реализаций String потребуется 2 байта на каждый символ (Java 64bit). Подробная информация здесь: Как решить InvalidKeyException
В этом случае упомянутая ошибка исчезнет только при использовании мягкой или более длинной клавиши, например:
static String PLAIN_TEXT = "SS18617710213463";
static String ENCRYPTION_KEY = "mykey@91mykey@91";
Однако есть еще одна важная вещь для рассмотрения. Реализация Java должна соответствовать точным алгоритмам, предоставленным node.js. Это не так просто, как кажется (по крайней мере, исходя из моего опыта). В вашем случае я бы предложил вам использовать node-forge на стороне node.js, что проще для реализации Java:
var forge = require('node-forge');
var plaintext = 'SS18617710213463';
var key = 'mykey@91mykey@91';
var iv = 'AODVNUASDNVVAOVF';
console.log('Plain Text: ' + plaintext);
var cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(plaintext));
cipher.finish();
var encrypted = cipher.output;
var encodedB64 = forge.util.encode64(encrypted.data);
console.log("Encoded: " + encodedB64);
var decodedB64 = forge.util.decode64(encodedB64);
encrypted.data = decodedB64;
var decipher = forge.cipher.createDecipher('AES-CBC', key);
decipher.start({iv: iv});
decipher.update(encrypted);
var result = decipher.finish();
console.log("Decoded: " + decipher.output.data);
Запустив код выше, вывод должен быть:
Plain Text: SS18617710213463
Encoded: HCzZD7uc13fqfM6odWcXf/mdR4aNJfkMDhEbnU+asjE=
Decoded: SS18617710213463
И совместимый код Java, который будет работать таким же образом, выглядит как код ниже:
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Main {
static String PLAIN_TEXT = "SS18617710213463";
static String ENCRYPTION_KEY = "mykey@91mykey@91";
static String INITIALIZATIO_VECTOR = "AODVNUASDNVVAOVF";
public static void main(String [] args) {
try {
System.out.println("Plain text: " + PLAIN_TEXT);
byte[] encryptedMsg = encrypt(PLAIN_TEXT, ENCRYPTION_KEY);
String base64Encrypted = Base64.getEncoder().encodeToString(encryptedMsg);
System.out.println("Encrypted: "+ base64Encrypted);
byte[] base64Decrypted = Base64.getDecoder().decode(base64Encrypted);
String decryptedMsg = decrypt(base64Decrypted, ENCRYPTION_KEY);
System.out.println("Decrypted: " + decryptedMsg);
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
}
Который производит:
Plain text: SS18617710213463
Encrypted: HCzZD7uc13fqfM6odWcXf/mdR4aNJfkMDhEbnU+asjE=
Decrypted: SS18617710213463