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

时间:2015-12-11 15:43:12

标签: java encryption rsa jks

我使用KeyStore Explorer创建了一个 KeyStore ,其中包含 RSA,4096字节和PKCS#8格式的公钥/私钥对

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

"算法RSA的密钥不适合对称加密。"

这对我来说并不合理,因为我使用非对称密钥加密/解密。我不确定从这里去哪里或我做错了什么。

这就是我所拥有的:

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;
}

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

1 个答案:

答案 0 :(得分:1)

您正尝试将密码初始化为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的一个很好的例子。