我正在用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个字节
答案 0 :(得分:2)
得到Invalid AES key length: 8 bytes invalid AES
的原因与键和文本的长度有关。您需要确保其长度(以位为单位)为2的幂。如果要使用字符串作为加密密钥,请检查其长度(以字节为单位),然后乘以8以找到以位为单位的长度。同样,大多数String实现都需要每个字符2个字节(Java 64位)。这里的详细信息:How to solve InvalidKeyException
在这种情况下,仅使用填充键或更长的键,上述错误就会消失,例如:
static String PLAIN_TEXT = "SS18617710213463";
static String ENCRYPTION_KEY = "mykey@91mykey@91";
但是,还有另一件事要考虑。 Java实现必须匹配node.js提供的确切算法。这并不像听起来那么容易(至少根据我的经验)。对于您的情况,我建议您在node.js端使用node-forge,这样更容易匹配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