Java中的AES加密,JavaScript中的解密
我正在开发一个应用程序(Java),其中一个私钥将被加密并发送到服务器。服务器将把密钥发送到一个网页,在那里它将被解密和使用(Javascript) 现在我有密码,但它不起作用。 解密失败 加密的工作原理如下: Java代码(加密): 密钥->编码->基64编码->AES加密->基64编码Java中的AES加密,JavaScript中的解密,javascript,java,encryption,aes,Javascript,Java,Encryption,Aes,我正在开发一个应用程序(Java),其中一个私钥将被加密并发送到服务器。服务器将把密钥发送到一个网页,在那里它将被解密和使用(Javascript) 现在我有密码,但它不起作用。 解密失败 加密的工作原理如下: Java代码(加密): 密钥->编码->基64编码->AES加密->基64编码 public static Keys genKeys(String password){ KeyPair keypair = genKeyPair(); Keys ke
public static Keys genKeys(String password){
KeyPair keypair = genKeyPair();
Keys keys = new Keys(keypair.getPublic(), encryptKey(keypair.getPrivate(), password));
return keys;
}
public static String encryptKey(PrivateKey priv, String password){
byte[] encodedKey = priv.getEncoded();
String base64Key = encodeBase64(encodedKey);
return encryptWithAES(base64Key.getBytes(), password);
}
protected static String encryptWithAES(byte[] msg, String password){
try {
String salt = new String(Hex.encodeHex(generateRandom(keySize / 8)));
String iv = new String(Hex.encodeHex(generateRandom(IV_SIZE / 8)));
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), Hex.decodeHex(salt.toCharArray()), iterationCount, keySize);
SecretKey secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(Hex.decodeHex(iv.toCharArray())));
byte[] encrypted = cipher.doFinal(msg);
String encryptedBase64 = encodeBase64(encrypted);
return salt + iv + encryptedBase64;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
}
return null;
}
public static String encodeBase64(byte[] encoded){
return Base64.encodeToString(encoded, Base64.NO_PADDING);
}
Javascriptcode(解密):
Base64编码->加密密钥->解密密钥
var key = decryptAES(password, keyBase64)
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(key);
var lon = decrypt.decrypt(json.lon);
var lat = decrypt.decrypt(json.lat);
var lonLat = new OpenLayers.LonLat(lon, lat)
}
function decryptAES(password, cipherText) {
keySize = 256;
ivSize = 128;
iterationCount = 1867;
let ivLength = ivSize / 4;
let saltLength = keySize / 4;
let salt = cipherText.substr(0, saltLength);
let iv = cipherText.substr(saltLength, ivLength);
let encrypted = cipherText.substring(ivLength + saltLength);
let key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {
keySize: keySize / 32,
iterations: iterationCount
});
let cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(encrypted)
});
let decrypted = CryptoJS.AES.decrypt(cipherParams, key, {iv: CryptoJS.enc.Hex.parse(iv)});
return decrypted.toString(CryptoJS.enc.Utf8);
}
有人知道我做错了什么吗?您在Javascript端调试了salt&iv吗?您是否调试了在Java和Javascript端生成的密钥?我看不到Java端的键大小、ivSize和迭代次数。为什么不运行一个简单的示例,只对样本数据进行加密,并尝试在Javascript端解密密文,而不使用“privateKey部分”。最后:您正在将数据解密为字符串,但RSA私钥是一个(编码的)字节数组,其中包含大量不可打印的字节,因此您应该将其保留在字节数组中,以供下一步使用;专用静态最终内部IV_长度=IV_尺寸/4;私有静态int-keySize=256;私有静态int迭代计数=1867;私有静态int-saltLength=keySize/4;`我已经调试过了,salt&iv还可以。privatekey在加密之前被编码为base64字符串,因此这也不应该是问题所在。我创建了一个较小的单元,没有发现为什么加密不起作用的错误。在javascript中解密后,我得到了一个空字符串。我发现了错误。这是因为base64。我仍然不确定问题出在哪里,我将Base64.encodeToString更改为DatatypeConverter.printBase64Binary,它成功了。我在输出中看到的一个区别是,它包含了填充,但不知道这是否必要。尽管如此,它还是有效的!:)我很高兴看到这个好消息:-)