BouncyCastle 密钥转换 - Java pkcs1格式,pkcs8格式互转
Posted LiuYanYGZ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BouncyCastle 密钥转换 - Java pkcs1格式,pkcs8格式互转相关的知识,希望对你有一定的参考价值。
摘自:https://www.cnblogs.com/ylz8401/p/9004427.html
1. PKCS#8 转 PKCS#1
You will need BouncyCastle:
import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter;
The code snippets below have been checked and found working with Bouncy Castle 1.52.
Private key
Convert private key from PKCS8 to PKCS1:
PrivateKey priv = pair.getPrivate(); byte[] privBytes = priv.getEncoded(); PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes); ASN1Encodable encodable = pkInfo.parsePrivateKey(); ASN1Primitive primitive = encodable.toASN1Primitive(); byte[] privateKeyPKCS1 = primitive.getEncoded(); ====> //pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[] PrivateKeyInfo pki = PrivateKeyInfo.getInstance(encodeByte); RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.getPrivateKey()); byte[] pkcs1Bytes = pkcs1Key.getEncoded();//etc.
Convert private key in PKCS1 to PEM:
PemObject pemObject = new PemObject("RSA PRIVATE KEY", privateKeyPKCS1); StringWriter stringWriter = new StringWriter(); PemWriter pemWriter = new PemWriter(stringWriter); pemWriter.writeObject(pemObject); pemWriter.close(); String pemString = stringWriter.toString();
Check with command line OpenSSL that the key format is as expected:
openssl rsa -in rsa_private_key.pem -noout -text
2. PKCS#1 转 PKCS#8
//format PKCS#1 to PKCS#8 public static String formatPkcs1ToPkcs8(String rawKey) throws Exception { String result = null; //extract valid key content String validKey = RsaPemUtil.extractFromPem(rawKey); if(!Strings.isNullOrEmpty(validKey)) { //将BASE64编码的私钥字符串进行解码 byte[] encodeByte = Base64.decodeBase64(validKey); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag); //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte); PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object); byte[] pkcs8Bytes = privKeyInfo.getEncoded(); String type = "PRIVATE KEY"; result = format2PemString(type, pkcs8Bytes); } return result; }
Notice:
生成出来的代码与openssl转换的还是有点不一样,主要是第一行。可能是有些属性字段不同,但经测试上述代码转换产生的key也可以解码。
3. 完整代码
import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Security; import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.util.io.pem.PemWriter; import org.bouncycastle.openssl.MiscPEMGenerator; import org.bouncycastle.openssl.PKCS8Generator; import com.ctrip.lzyan.test.cipher.cscm.RsaPemUtil; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.apache.commons.codec.binary.Base64; /** * Transform PKCS format * PKCS#1 -> PKCS#8 * PKCS#8 -> PKCS#1 * */ public class RsaPkcsTransformer { private static final String COMMENT_BEGIN_FLAG = "-----"; private static final String RETURN_FLAG_R = "\\r"; private static final String RETURN_FLAG_N = "\\n"; //format PKCS#8 to PKCS#1 public static String formatPkcs8ToPkcs1(String rawKey) throws Exception { String result = null; //extract valid key content String validKey = RsaPemUtil.extractFromPem(rawKey); if(!Strings.isNullOrEmpty(validKey)) { //将BASE64编码的私钥字符串进行解码 byte[] encodeByte = Base64.decodeBase64(validKey); //========== //pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[] PrivateKeyInfo pki = PrivateKeyInfo.getInstance(encodeByte); RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.getPrivateKey()); byte[] pkcs1Bytes = pkcs1Key.getEncoded();//etc. //========== String type = "RSA PRIVATE KEY"; result = format2PemString(type, pkcs1Bytes); } return result; } //format PKCS#1 to PKCS#8 public static String formatPkcs1ToPkcs8(String rawKey) throws Exception { String result = null; //extract valid key content String validKey = RsaPemUtil.extractFromPem(rawKey); if(!Strings.isNullOrEmpty(validKey)) { //将BASE64编码的私钥字符串进行解码 byte[] encodeByte = Base64.decodeBase64(validKey); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag); //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte); PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object); byte[] pkcs8Bytes = privKeyInfo.getEncoded(); String type = "PRIVATE KEY"; result = format2PemString(type, pkcs8Bytes); } return result; } // Write to pem file private static String format2PemString(String type, byte[] privateKeyPKCS1) throws Exception { PemObject pemObject = new PemObject(type, privateKeyPKCS1); StringWriter stringWriter = new StringWriter(); PemWriter pemWriter = new PemWriter(stringWriter); pemWriter.writeObject(pemObject); pemWriter.close(); String pemString = stringWriter.toString(); return pemString; } //=== Testing === public static void main(String[] args) throws Exception { String rawKey_pkcs1 = "MIICXQIBAAKBgQDgDxka1U8SWI1vBY7pA1UiCVnrdtSgE+PpyTqe2YSEWCgkYQ2YsohZwsaUao7nya7QnBgRiPKEHgS/Eey+L9iwo32Sn5fUwb0nJ1+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0GyLTQuZGadFVuVq2dQqEsrq7HwIDAQABAoGAYtaGLo4WWXNywJzlE+kCbwdNAU/kL9FWYtT/5P7zNCZnXtTpWIi5GU+QpfvzmlAfq6qP+3w77wgG8/qGQsd8gGu3mydi0ImmD9sJdhhsJuWZhCMM+qmvSmvG/gvIr+bdEmphpCQpa3BLveUkFDA/OnwfTVL6ruwZayMzuToB6WECQQD63Gx9DZVhYoSxR7qSmiGf/TjfOJusTcrmc27Z5X5MS36a3Ux9Z+c9EaYFldZ3cPzP521ugNVvZdovKqFKIcQ5AkEA5KYeKBVlkrLaamSEu5WAX3DqJ6iDRqEjzMoVad5B1I7kJHO+NijUxNHaWaSqLOHuk37X+EAjSTozzwOkKwbqFwJBAM1NhhAWBNHtcdEwddWzBJ/N+jRdPLIX/Fz7zZXQRruj8VpGkGn1lf6ZqfjaNuoLcyunKB0OnR6NCbIePl/QIKkCQGgEQjfN9BVWlBJOhCuqCWphvcQo3v+kktq5HCC7YYtHLfZ/SQrubEzVgtXBGUGtzpD+5VUkKGlJtwP4Dhkc3iUCQQCwiFKuQe/OdlkYk1L4mb0H0fzy+/6mYxyUqpTXUw/6BVDOyowvzieh9oh2ZhnQS7YPBWz5ZXzwUH4YVwGqxiwA"; String rawKey_pkcs8 = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQqk40miMhsXad+Actaw2fhvOflZ5tzpZkvHQbItNC5kZp0VW5WrZ1CoSyursfAgMBAAECgYBi1oYujhZZc3LAnOUT6QJvB00BT+Qv0VZi1P/k/vM0Jmde1OlYiLkZT5Cl+/OaUB+rqo/7fDvvCAbz+oZCx3yAa7ebJ2LQiaYP2wl2GGwm5ZmEIwz6qa9Ka8b+C8iv5t0SY+GkJClrcEu95SQUMD86fB9NUvqu7BlrIzO5OgHpYQJBAPrcbH0NlWFihLFHupKaIZ/9ON84m6xNyuZzbtnlfkxLfprdTH1n5z0RpgWV1ndw/M/nbW6A1W9l2i8qoUohxDkCQQDkph4oFWWSstpqZIS7lYBfcOonqINGoSPMyhVp3kHUjuQkc742KNTE0dpZpKos4e6Tftf4QCNJOjPPA6QrBuoXAkEAzU2GEBYE0e1x0TB11bMEn836NF08shf8XPvNldBGu6PxWkaQafWV/pmp+No26gtzK6coHQ6dHo0Jsh4+X9AgqQJAaARCN830FVaUEk6EK6oJamG9xCje/6SS2rkcILthi0ct9n9JCu5sTNWC1cEZQa3OkP7lVSQoaUm3A/gOGRzeJQJBALCIUq5B7852WRiTUviZvQfR/PL7/qZjHJSqlNdTD/oFUM7KjC/OJ6H2iHZmGdBLtg8FbPllfPBQfhhXAarGLAA="; //rawKey_pkcs1 = "MIICXAIBAAKBgQC0Y9rmhe4fIsFrrm0m/jrbfZsqxMYvg8qdvbSGHC9vnYm4K5p3bFBqqULAFlv2ZGjrWDFcBfa562E5hXtAoACXtsDH8WCkhfNiPkGQn3wNDGRpfYVup/F1LdceunSu0IYDP0MACzKY1S7KM2qJi8P8YlXZ91oyRfgb8lgqdQoXmQIDAQABAoGAIG90BM9AKckODlamucQswRqss9v95r1DyWk69IJM5Tzmbn8onyCStRsKLY/XqU4Ur3yEI4/O9U8lhDpEFzKt6ExkITkiVcVlRuK0lkAKS4Uu4W+YoPzNLwKoL3dS1my+wPOxgswJ+QPSrYfWoGDoDNiZctskcHprplkECYI9/aECQQDXvkZl9IHXRolUCQWfS5MFWVgPwaXNP3X3gXaqdfhoopIPsZphurd+hxDWforh+KNkdRejbbwIveGTxkXqxTe3AkEA1gzPz9IAzFPx8RjkOxgRag3g+Rp+35nuLw18Rt04EODinurCsg3t5k2rOx2Fic6GVozqM3B3p4ATr4GsyhALLwJAFi8vp/47d7p+FpES7e1kgdFNF9muxes3oyrB3Adjcsb8w/ZcTJ5Zjf4vgg7jExdxHbxYoOqAwllcH8jsmZaMAwJAXdJjzF3qR6WL6PfWIijciTXoJIf+kJfyFOG+VXllt9A6xRl1mYINguMMaO75t3u02n8NsNpdOCgleMpIKJF7tQJBALsDYb59npdnKL2V0zk5bZ7Nd40dy4KbRcXIG2Ll/Lo6CeY/6Jes868R0yyuyLGP5CcayMKVAhcVk3xEWI7dluU="; String formatKey = formatPkcs1ToPkcs8(rawKey_pkcs1); //String formatKey = formatPkcs8ToPkcs1(rawKey_pkcs8); System.out.println(formatKey); //expect: abcdef } }
package com.ctrip.lzyan.test.element.rsa.sample4; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; /** * * RSA+Base64加密解密工具类 RSA 一般用在数据传输过程中的加密和解密 先用RSA加密后是字节数组 再用BASE64加密 成字符串进行传输 测试 * RSA1024产生的公钥字节长度在160-170之间 私钥长度在630-640之间 经过base64加密后长度 公钥字节产度在210-220之间 * 私钥长度在840-850之间 所以数据库设计时如果存公钥长度设计varchar(256) 私钥长度varchar(1024) * */ public abstract class LzyanRSAUtilTest2 { public static final String KEY_ALGORITHM = "RSA"; private static final String PUBLIC_KEY = "rsa_public_key"; private static final String PRIVATE_KEY = "rsa_private_key"; private static final String ENCODING = "UTF-8"; /** * * 加密 * 用公钥加密 * @param content * @param base64PublicKeyStr * @return * @throws Exception */ public static String encryptByPublicKey(String content, String base64PublicKeyStr) throws Exception { byte[] inputBytes = content.getBytes(ENCODING); byte[] outputBytes = encryptByPublicKey(inputBytes, base64PublicKeyStr); return Base64.encodeBase64String(outputBytes); } /** * * 加密 * * 用私钥加密 * @param content * @param base64PrivateKeyStr * @return * @throws Exception */ public static String encryptByPrivateKey(String content, String base64PrivateKeyStr) throws Exception { byte[] inputBytes = content.getBytes(ENCODING); byte[] outputBytes = encryptByPrivateKey(inputBytes, base64PrivateKeyStr); return Base64.encodeBase64String(outputBytes); } /** * * 解密 * 用公钥解密 * @param content * @param base64PublicKeyStr * @return * @throws Exception */ public static String decryptByPublicKey(String content, String base64PublicKeyStr) throws Exception { byte[] inputBytes = Base64.decodeBase64(content); byte[] outputBytes = decryptByPublicKey(inputBytes, base64PublicKeyStr); return new String(outputBytes, ENCODING); } /** * * 解密 * 用私钥解密 * @param content * @param privateKeyStr * @return * @throws Exception */ public static String decryptByPrivateKey(String content, String base64PrivateKeyStr) throws Exception { byte[] inputBytes = Base64.decodeBase64(content); byte[] outputBytes = decryptByPrivateKey(inputBytes, base64PrivateKeyStr); return new String(outputBytes, ENCODING); } /** * * 加密 * 用公钥加密 * @param content * @param base64PublicKeyStr * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] content, String base64PublicKeyStr) throws Exception { // 对公钥解密 byte[] publicKeyBytes = Base64.decodeBase64(base64PublicKeyStr); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(content); } /** * * 加密 * 用私钥加密 * @param content * @param base64PrivateKeyStr * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] content, String base64PrivateKeyStr) throws Exception { // 对密钥解密 byte[] privateKeyBytes = Base64.decodeBase64(base64PrivateKeyStr); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(content); } /** * * 解密 * 用公钥解密 * @param content * @param base64PublicKeyStr * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] content, String base64PublicKeyStr) throws Exception { // 对密钥解密 byte[] publicKeyBytes = Base64.decodeBase64(base64PublicKeyStr); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(content); } /** * 解密 * 用私钥解密 * @param content * @param privateKeyStr * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] content, String base64PrivateKeyStr) throws Exception { // 对密钥解密 byte[] privateKeyBytes = Base64.decodeBase64(base64PrivateKeyStr); // 取得私钥 for PKCS#1 // RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(privateKeyBytes)); // RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent()); // KeyFactory keyFactory= KeyFactory.getInstance("RSA"); // PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec); // 取得私钥 for PKCS#8 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, priKey); return cipher.doFinal(content); } /** * * 取得私钥 * @param keyMap * @return * @throws Exception */ public static String getBase64PrivateKeyStr(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64.encodeBase64String(key.getEncoded()); } /** * * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getBase64PublicKeyStr(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64.encodeBase64String(key.getEncoded()); } /** * * 初始化密钥 * @return * @throws Exception */ public static Map initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); // 初始化RSA1024安全些 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 公钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 私钥 Map keyMap = new HashMap(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } private static void test() throws Exception { String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgDxka1U8SWI1vBY7pA1UiCVnr" + "dtSgE+PpyTqe2YSEWCgkYQ2YsohZwsaUao7nya7QnBgRiPKEHgS/Eey+L9iwo32S" + "n5fUwb0nJ1+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0GyLTQuZG" + "adFVuVq2dQqEsrq7HwIDAQAB"; String str = "123456"; String content = encryptByPublicKey(str, pubKey); System.out.println(content); String priKey_pkcs1 = "MIICXQIBAAKBgQDgDxka1U8SWI1vBY7pA1UiCVnrdtSgE+PpyTqe2YSEWCgkYQ2YsohZwsaUao7nya7QnBgRiPKEHgS/Eey+L9iwo32Sn5fUwb0nJ1+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0GyLTQuZGadFVuVq2dQqEsrq7HwIDAQABAoGAYtaGLo4WWXNywJzlE+kCbwdNAU/kL9FWYtT/5P7zNCZnXtTpWIi5GU+QpfvzmlAfq6qP+3w77wgG8/qGQsd8gGu3mydi0ImmD9sJdhhsJuWZhCMM+qmvSmvG/gvIr+bdEmPhpCQpa3BLveUkFDA/OnwfTVL6ruwZayMzuToB6WECQQD63Gx9DZVhYoSxR7qSmiGf/TjfOJusTcrmc27Z5X5MS36a3Ux9Z+c9EaYFldZ3cPzP521ugNVvZdovKqFKIcQ5AkEA5KYeKBVlkrLaamSEu5WAX3DqJ6iDRqEjzMoVad5B1I7kJHO+NijUxNHaWaSqLOHuk37X+EAjSTozzwOkKwbqFwJBAM1NhhAWBNHtcdEwddWzBJ/N+jRdPLIX/Fz7zZXQRruj8VpGkGn1lf6ZqfjaNuoLcyunKB0OnR6NCbIePl/QIKkCQGgEQjfN9BVWlBJOhCuqCWphvcQo3v+kktq5HCC7YYtHLfZ/SQrubEzVgtXBGUGtzpD+5VUkKGlJtwP4Dhkc3iUCQQCwiFKuQe/OdlkYk1L4mb0H0fzy+/6mYxyUqpTXUw/6BVDOyowvzieh9oh2ZhnQS7YPBWz5ZXzwUH4YVwGqxiwA"; String priKey_pkcs8_openssl = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQqk40miMhsXad+Actaw2fhvOflZ5tzpZkvHQbItNC5kZp0VW5WrZ1CoSyursfAgMBAAECgYBi1oYujhZZc3LAnOUT6QJvB00BT+Qv0VZi1P/k/vM0Jmde1OlYiLkZT5Cl+/OaUB+rqo/7fDvvCAbz+oZCx3yAa7ebJ2LQiaYP2wl2GGwm5ZmEIwz6qa9Ka8b+C8iv5t0SY+GkJClrcEu95SQUMD86fB9NUvqu7BlrIzO5OgHpYQJBAPrcbH0NlWFihLFHupKaIZ/9ON84m6xNyuZzbtnlfkxLfprdTH1n5z0RpgWV1ndw/M/nbW6A1W9l2i8qoUohxDkCQQDkph4oFWWSstpqZIS7lYBfcOonqINGoSPMyhVp3kHUjuQkc742KNTE0dpZpKos4e6Tftf4QCNJOjPPA6QrBuoXAkEAzU2GEBYE0e1x0TB11bMEn836NF08shf8XPvNldBGu6PxWkaQafWV/pmp+No26gtzK6coHQ6dHo0Jsh4+X9AgqQJAaARCN830FVaUEk6EK6oJamG9xCje/6SS2rkcILthi0ct9n9JCu5sTNWC1cEZQa3OkP7lVSQoaUm3A/gOGRzeJQJBALCIUq5B7852WRiTUviZvQfR/PL7/qZjHJSqlNdTD/oFUM7KjC/OJ6H2iHZmGdBLtg8FbPllfPBQfhhXAarGLAA="; String priKey_pkcs8_new = "MIICdwIBADANBgsqhkiG9w0BDAoBAgSCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQqk40miMhsXad+Actaw2fhvOflZ5tzpZkvHQbItNC5kZp0VW5WrZ1CoSyursfAgMBAAECgYBi1oYujhZZc3LAnOUT6QJvB00BT+Qv0VZi1P/k/vM0Jmde1OlYiLkZT5Cl+/OaUB+rqo/7fDvvCAbz+oZCx3yAa7ebJ2LQiaYP2wl2GGwm5ZmEIwz6qa9Ka8b+C8iv5t0SY+GkJClrcEu95SQUMD86fB9NUvqu7BlrIzO5OgHpYQJBAPrcbH0NlWFihLFHupKaIZ/9ON84m6xNyuZzbtnlfkxLfprdTH1n5z0RpgWV1ndw/M/nbW6A1W9l2i8qoUohxDkCQQDkph4oFWWSstpqZIS7lYBfcOonqINGoSPMyhVp3kHUjuQkc742KNTE0dpZpKos4e6Tftf4QCNJOjPPA6QrBuoXAkEAzU2GEBYE0e1x0TB11bMEn836NF08shf8XPvNldBGu6PxWkaQafWV/pmp+No26gtzK6coHQ6dHo0Jsh4+X9AgqQJAaARCN830FVaUEk6EK6oJamG9xCje/6SS2rkcILthi0ct9n9JCu5sTNWC1cEZQa3OkP7lVSQoaUm3A/gOGRzeJQJBALCIUq5B7852WRiTUviZvQfR/PL7/qZjHJSqlNdTD/oFUM7KjC/OJ6H2iHZmGdBLtg8FbPllfPBQfhhXAarGLAA="; String priKey = priKey_pkcs8_new; String output = decryptByPrivateKey(content, priKey); System.out.println(output); } // === Testing === public static void main(String[] args) throws Exception { test(); } }
4. Java中使用PKCS#1秘钥
要引入一个bouncycastle包(bcprov-jdk16),代码多几行。
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk16</artifactId> <version>1.46</version> </dependency>
// 取得私钥 for PKCS#1 RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(privateKeyBytes)); RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent()); KeyFactory keyFactory= KeyFactory.getInstance("RSA"); PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec); // 取得私钥 for PKCS#8 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
以上是关于BouncyCastle 密钥转换 - Java pkcs1格式,pkcs8格式互转的主要内容,如果未能解决你的问题,请参考以下文章
Java 中带有 bouncycastle 的 PBKDF2
如何在 BouncyCastle 中向 ASN1EncodableVector 添加特定的“密钥”?
java.lang.IllegalArgumentException:字符串curve25519不是OID bouncycastle 1.52
如何使用 BouncyCastle 解密,使用 GCM Tag 的字符串,IV 字符串和密钥字符串,所有这些都是十六进制的?
无法将“Org.BouncyCastle.Asn1.DerSequence”类型的对象转换为“Org.BouncyCastle.Asn1.DerInteger”类型