Java中的AES加密,JavaScript中的解密

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

我正在开发一个应用程序(Java),其中一个私钥将被加密并发送到服务器。服务器将把密钥发送到一个网页,在那里它将被解密和使用(Javascript)

现在我有密码,但它不起作用。 解密失败

加密的工作原理如下:

Java代码(加密):

密钥->编码->基64编码->AES加密->基64编码

    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,它成功了。我在输出中看到的一个区别是,它包含了填充,但不知道这是否必要。尽管如此,它还是有效的!:)我很高兴看到这个好消息:-)