一、DER编码密钥对
先说下DER编码,是因为JCE本身是支持DER编码密钥对的解析的,可以参见PKCS8EncodedKeySpec和X509EncodedKeySpec.
DER编码是ASN.1编码规则中的一个子集,具体格式如何编排没有去了解,但最终呈现肯定的是一堆有规律的二进制组合而成。
PKCS#8定义了私钥信息语法和加密私钥语法,而X509定义证书规范,通常都会用DER和PEM进行编码存储,而在JAVA中则使用的
DER。
接下来看看如果通过DER编码的密钥对分别获取JAVA的公私钥对象。
1.下面一段是生成私钥对象的,传入参数是DER编码的私钥内容。
@Override
public PrivateKey generatePrivateKey(byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec keySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
2.下面是生成公钥对象的,传入参数是DER编码公钥内容,可以看到和生成私钥的部分非常相似。
public PublicKey geneneratePublicKey(byte[] key) throws InvalidKeySpecException, NoSuchAlgorithmException{
KeySpec keySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
二、PEM编码
PEM编码也是密钥对较常用的编码方式,openssl则是以PEM编码为主,相对DER对人可读性更强,以BASE64编码呈现,外围包上类似-----BEGIN RSA PRIVATE KEY-----。
JCE没有对PEM直接支持的方式,但是可以通过第三方包例如bouncycastle解析,当然如果想要自己理解pem编码结构,也可以自己写代码解析。
这里介绍下如何使用bouncycastle进行解析。
FileInputStream fis = new FileInputStream("id_rsa");
byte[] key = PrivateKeyUtils.readStreamToBytes(fis);
Security.addProvider(new BouncyCastleProvider());