在 Java 中,如何使用 JKS 密钥库中 X509 证书(public/private 密钥对)的私钥进行解密?

In Java, how do I decrypt using the private key from an X509 certificate (public/private key pair) inside a JKS keystore?

我使用 KeyStore Explorer 创建了一个 KeyStore,里面有 public/private 密钥对 RSA、4096 字节和 PKCS#8 格式

当我的代码运行并点击 cipher.init() 方法时,我收到 错误

"Key for algorithm RSA not suitable for symmetric encryption."

这对我来说没有意义,因为我使用的是非对称密钥 encryption/decryption。我不确定从这里去哪里或我做错了什么。

这是我的资料:

public TransactionData processData(TransactionData data) throws BTHException {
    String keystoreFilePath = manager.getStringValue(KeyStoreFilePath);
    String keystorePassword = manager.getStringValue(KeyStoreFilePassword);
    String privateKeyPassword = manager.getStringValue(KeyStorePrivateKeyPassword);
    String certificateAlias = manager.getStringValue(CertificateAlias);

    org.apache.xml.security.Init.init();

    try {
        InputStream in = data.getDataStream();
        byte[] dataBytes = DataUtil.readBytes(in);
        String encryptedDataStr = new String(dataBytes);

        PrivateKey privateKey = getPrivateKeyFromKeyStore(keystoreFilePath, keystorePassword, certificateAlias, privateKeyPassword);

        decrypt(
            encryptedDataStr,
            privateKey
        );
    }catch(Exception e){
        throw new BTHException(e.getMessage());
    }

    return data;
}

private PrivateKey getPrivateKeyFromKeyStore(String keyStoreFilePath, String keyStorePassword, String privateKeyCertAlias, String privateKeyPassword) throws BTHException {
    PrivateKey privateKey = null;
    try {
        KeyStore keystore = KeyStore.getInstance("JKS");
        BASE64Encoder encoder = new BASE64Encoder();
        keystore.load(new FileInputStream(keyStoreFilePath), keyStorePassword.toCharArray());
        Key key=keystore.getKey(privateKeyCertAlias,keyStorePassword.toCharArray());
        if(key instanceof PrivateKey) {
            Certificate cert=keystore.getCertificate(privateKeyCertAlias);
            PublicKey publicKey=cert.getPublicKey();
            KeyPair keyPair = new KeyPair(publicKey,(PrivateKey)key);
            privateKey = keyPair.getPrivate();
        }
        //privateKeyEncoded = encoder.encode(privateKey.getEncoded());
    } catch (Exception e) {
        throw new BTHException(e.getMessage());
    }
    return privateKey;
}

private String decrypt(String cipherText, PrivateKey privateKey) throws IOException, GeneralSecurityException, BTHException {
    String decryptedValue = null;

    try {
        // 1. Get the cipher ready to start doing the AES transformation
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        // 2. Start the decryption process
        // THIS IS WHERE IT FAILS
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // 3. Finish the decryption process
        decryptedValue = new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8");
    } catch (Exception e) {
        throw new BTHException(e.getMessage());
    }

    return decryptedValue;
}

任何帮助都会很棒。提前致谢!

您正在尝试将您的密码初始化为 AES/CBC/PKCS5Padding,这是一个 对称加密,这就是异常的来源。

你应该这样使用 Cipher:

// 1. Get the cipher ready to start doing the RSA transformation
Cipher cipher = Cipher.getInstance("RSA");

// 2. Start the decryption process
cipher.init(Cipher.DECRYPT_MODE, privateKey);

在这里您可以找到 RSA-Encryption and Decryption 的一个很好的例子。