如何在Java中解密带密码短语的RSA加密私钥?
在Java中解密PKCS#1格式的加密RSA私钥
你的需求是实现OpenSSL命令 openssl rsa -in enc_private.key -out private.key -passin pass:passphrase_xyz 的功能,也就是解密带密码的PKCS#1格式RSA私钥。JDK原生API对这种格式的加密私钥支持有限,推荐使用BouncyCastle库来处理。
步骤1:引入BouncyCastle依赖
如果用Maven,在pom.xml中添加:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency>
Gradle则添加:
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
步骤2:实现解密代码
以下是完整的Java代码,包含加载加密私钥、解密、以及可选的保存解密后的私钥到文件:
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; import java.io.FileReader; import java.io.FileWriter; import java.security.KeyPair; import java.security.Security; import java.security.PrivateKey; public class RSAKeyDecryptor { public static void main(String[] args) throws Exception { // 注册BouncyCastle加密提供者 Security.addProvider(new BouncyCastleProvider()); String encryptedKeyPath = "enc_private.key"; String decryptedKeyPath = "private.key"; String passphrase = "passphrase_xyz"; // 加载并解密私钥 PrivateKey privateKey = decryptEncryptedRsaPrivateKey(encryptedKeyPath, passphrase); // 可选:将解密后的私钥保存为PEM文件 savePrivateKeyToPem(privateKey, decryptedKeyPath); } private static PrivateKey decryptEncryptedRsaPrivateKey(String keyPath, String passphrase) throws Exception { try (PEMParser pemParser = new PEMParser(new FileReader(keyPath))) { Object object = pemParser.readObject(); PEMDecryptorProvider decryptorProvider = new JcePEMDecryptorProviderBuilder() .setProvider("BC") .build(passphrase.toCharArray()); PEMKeyPair pemKeyPair; if (object instanceof PEMEncryptedKeyPair) { // 处理加密的密钥对 pemKeyPair = ((PEMEncryptedKeyPair) object).decryptKeyPair(decryptorProvider); } else { throw new IllegalArgumentException("输入的不是加密的RSA私钥文件"); } // 转换为Java标准PrivateKey对象 JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); KeyPair keyPair = converter.getKeyPair(pemKeyPair); return keyPair.getPrivate(); } } private static void savePrivateKeyToPem(PrivateKey privateKey, String outputPath) throws Exception { // 将PrivateKey转换为PKCS#1格式的PEM字符串 JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded()); String pemHeader = "-----BEGIN RSA PRIVATE KEY-----"; String pemFooter = "-----END RSA PRIVATE KEY-----"; String pemContent = org.bouncycastle.util.encoders.Base64.toBase64String(privateKeyInfo.parsePrivateKey().getEncoded()); // 按OpenSSL格式分段写入(每行64字符) try (FileWriter writer = new FileWriter(outputPath)) { writer.write(pemHeader + "\n"); for (int i = 0; i < pemContent.length(); i += 64) { int end = Math.min(i + 64, pemContent.length()); writer.write(pemContent.substring(i, end) + "\n"); } writer.write(pemFooter); } } }
关键说明
- 你的私钥是PKCS#1格式(开头是
-----BEGIN RSA PRIVATE KEY-----),BouncyCastle的PEMEncryptedKeyPair可以直接处理这种格式的加密私钥。 - 代码指定BouncyCastle作为提供者,确保支持你私钥文件中指定的
DES-EDE3-CBC(3DES)加密算法。 - 解密后的私钥可直接用于RSA签名、解密等操作,保存后的文件格式和OpenSSL命令输出完全一致。
内容的提问来源于stack exchange,提问作者user3447
相关产品推荐
相关产品推荐

