BouncyCastle密钥转换-Javapkcs1格式,pkcs8格式互转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 = Private();
byte[] privBytes = Encoded();
PrivateKeyInfo pkInfo = Instance(privBytes);
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = ASN1Primitive();
byte[] privateKeyPKCS1 = Encoded();
====>
//pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[]
PrivateKeyInfo pki = Instance(encodeByte);
RSAPrivateKeyStructure pkcs1Key = PrivateKey());
byte[] pkcs1Bytes = Encoded();//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 = String();
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 = actFromPem(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 = Encoded();
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 pto.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;
st.cipher.cscm.RsaPemUtil;
lemon.base.Joiner;
lemon.base.Splitter;
lemon.base.Strings;
llect.Lists;
import dec.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 = actFromPem(rawKey);
if(!Strings.isNullOrEmpty(validKey)) {
//将BASE64编码的私钥字符串进⾏解码
byte[] encodeByte = Base64.decodeBase64(validKey);
//==========
//pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[]
PrivateKeyInfo pki = Instance(encodeByte);
RSAPrivateKeyStructure pkcs1Key = PrivateKey());
byte[] pkcs1Bytes = Encoded();//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 = actFromPem(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 = Encoded();
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 = String();
return pemString;
}
/
/=== Testing ===
public static void main(String[] args) throws Exception {
String rawKey_pkcs1 = "MIICXQIBAAKBgQDgDxka1U8SWI1vBY7pA1UiCVnrdtSgE+PpyTqe2YSEWCgkYQ2YsohZwsaUao7nya7QnBgRiPKEHgS/Eey+L9iwo32Sn5fUwb0nJ1+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0Gy        String rawKey_pkcs8 = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQqk4 //rawKey_pkcs1 = "MIICXAIBAAKBgQC0Y9rmhe4fIsFrrm0m/jrbfZsqxMYvg8qdvbSGHC9vnYm4K5p3bFBqqULAFlv2ZGjrWDFcBfa562E5hXtAoACXtsDH8WCkhfNiPkGQn3wNDGRpfYVup/F1LdceunSu0IYDP0MACzKY1S7KM2qJi8P8YlXZ9        String formatKey = formatPkcs1ToPkcs8(rawKey_pkcs1);
//String formatKey = formatPkcs8ToPkcs1(rawKey_pkcs8);
System.out.println(formatKey);    //expect: abcdef
}
}
st.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;
pto.Cipher;
import dec.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 = Bytes(ENCODING);
byte[] outputBytes = encryptByPublicKey(inputBytes, base64PublicKeyStr);
deBase64String(outputBytes);
}
/**
*
* 加密
*
* ⽤私钥加密
* @param content
* @param base64PrivateKeyStr
* @return
* @throws Exception
*/
public static String encryptByPrivateKey(String content, String base64PrivateKeyStr) throws Exception { byte[] inputBytes = Bytes(ENCODING);
byte[] outputBytes = encryptByPrivateKey(inputBytes, base64PrivateKeyStr);
deBase64String(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 = Instance(KEY_ALGORITHM);
Key publicKey = atePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Algorithm());
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 = Instance(KEY_ALGORITHM);
Key privateKey = atePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Algorithm());
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 = Instance(KEY_ALGORITHM);
Key publicKey = atePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Algorithm());
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 Modulus(), PrivateExponent());
//        KeyFactory keyFactory= Instance("RSA");
//        PrivateKey priKey= atePrivate(rsaPrivKeySpec);
// 取得私钥  for PKCS#8
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key priKey = atePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Algorithm());
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) (PRIVATE_KEY);
Encoded());
}
/**
*
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getBase64PublicKeyStr(Map keyMap) throws Exception {
Key key = (Key) (PUBLIC_KEY);
Encoded());
}
/**
*
* 初始化密钥
* @return
* @throws Exception
*/
public static Map initKey() throws Exception {
KeyPairGenerator keyPairGen = Instance(KEY_ALGORITHM);
keyPairGen.initialize(1024); // 初始化RSA1024安全些
KeyPair keyPair = ateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) Public(); // 公钥
RSAPrivateKey privateKey = (RSAPrivateKey) Private(); // 私钥
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+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0GyL        String priKey_pkcs8_openssl = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoG
BAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomw        String priKey_pkcs8_new = "MIICdwIBADANBgsqhkiG9w0BDAoBAgSCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQ        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 Modulus(), PrivateExponent());  KeyFactory keyFactory= Instance("RSA");
PrivateKey priKey= atePrivate(rsaPrivKeySpec);
// 取得私钥  for PKCS#8
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key priKey = atePrivate(pkcs8KeySpec);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。