如何用Java将PKCS#8私钥字符串转换为PKCS#1格式私钥
Java实现PKCS#8转PKCS#1私钥字符串的思路
核心步骤
- 解析PKCS#8私钥字符串:先去除PEM首尾标记,解码Base64内容得到DER字节数组,再通过Java标准库的
KeyFactory和PKCS8EncodedKeySpec解析为RSAPrivateKey对象。 - 转换为PKCS#1格式:PKCS#1的RSA私钥有特定的ASN.1结构,需要将
RSAPrivateKey的各个字段(模数、私钥指数、素数P/Q等)按结构组装。推荐用BouncyCastle库简化操作,避免手动拼接ASN.1序列。 - 生成PKCS#1的PEM字符串:将转换后的DER字节数组做Base64编码,加上PKCS#1的PEM首尾标记,按规范分割每行64个字符。
代码示例
import org.bouncycastle.asn1.pkcs.RSAPrivateKey; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.bouncycastle.util.io.pem.PemObject; import java.io.StringWriter; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; public class PKCS8ToPKCS1Converter { public static String convert(String pkcs8PrivateKeyStr) throws Exception { // 移除PKCS#8的PEM标记并清理空白 String cleanedPkcs8 = pkcs8PrivateKeyStr .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s", ""); // 解码Base64得到DER格式字节数组 byte[] pkcs8DerBytes = java.util.Base64.getDecoder().decode(cleanedPkcs8); // 解析为RSA私钥 KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(pkcs8DerBytes); PrivateKey privateKey = rsaKeyFactory.generatePrivate(pkcs8Spec); RSAPrivateKeySpec rsaSpec = rsaKeyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class); // 构建PKCS#1格式的ASN.1结构 RSAPrivateKey pkcs1RsaKey = RSAPrivateKey.getInstance( new org.bouncycastle.asn1.ASN1Sequence( new org.bouncycastle.asn1.ASN1Encodable[]{ new org.bouncycastle.asn1.ASN1Integer(0), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getModulus()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getPrivateExponent()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getPrimeP()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getPrimeQ()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getPrimeExponentP()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getPrimeExponentQ()), new org.bouncycastle.asn1.ASN1Integer(rsaSpec.getCrtCoefficient()) } ) ); byte[] pkcs1DerBytes = pkcs1RsaKey.getEncoded(); // 生成PKCS#1的PEM格式字符串 try (StringWriter writer = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(writer)) { pemWriter.writeObject(new PemObject("RSA PRIVATE KEY", pkcs1DerBytes)); pemWriter.flush(); return writer.toString(); } } public static void main(String[] args) throws Exception { // 示例PKCS#8私钥字符串 String pkcs8Key = "-----BEGIN PRIVATE KEY-----\n" + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4...省略内容...\n" + "-----END PRIVATE KEY-----"; String pkcs1Key = convert(pkcs8Key); System.out.println(pkcs1Key); } }
依赖说明
需要引入BouncyCastle的BCPKIX库,Maven依赖配置如下:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency>
注意事项
- 确保输入的PKCS#8私钥为RSA类型,非RSA私钥转换会报错。
- 处理Base64内容时需移除所有空白字符(换行、空格、制表符等),避免解码失败。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

