在 Java 中,如何使用来自 JKS 密钥库内的 X509 证书(公钥/私钥对)的私钥进行解密?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34227317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Java, how do I decrypt using the private key from an X509 certificate (public/private key pair) inside a JKS keystore?
提问by Brian T Hannan
I created a KeyStoreusing KeyStore Explorer with a public/private key pairinside it of type RSA, 4096 bytes, and PKCS#8 formatting.
我使用 KeyStore Explorer创建了一个KeyStore,里面有一个公钥/私钥对,类型为RSA、4096 字节和 PKCS#8 格式。
I get an errorwhen my code runs and hits the cipher.init()method :
当我的代码运行并命中cipher.init()方法时出现错误:
"Key for algorithm RSA not suitable for symmetric encryption."
“算法 RSA 的密钥不适合对称加密。”
This doesn't really make sense to me because I'm using asymmetric key encryption/decryption. I'm not sure where to go from here or what I'm doing wrong.
这对我来说没有意义,因为我使用的是非对称密钥加密/解密。我不知道从哪里开始或我做错了什么。
Here is what I have:
这是我所拥有的:
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;
}
Any help would be great. Thanks in advance!
任何帮助都会很棒。提前致谢!
采纳答案by Dennis Kriechel
You are trying to initialize your cipher as AES/CBC/PKCS5Padding
which is an symmetric encryptionand that is where the exception originates.
您正在尝试初始化密码为AES/CBC/PKCS5Padding
这是一种对称加密,这是异常源自哪里。
You should use the Cipher
like that:
你应该使用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);
Here you can find a good example for RSA-Encryption and Decryption.
在这里您可以找到RSA-Encryption 和 Decryption 的一个很好的例子。