如何生成X509EncodedKeySpec构造函数可接受的X509证书?

时间:2017-03-10 03:49:33

标签: java android rsa x509

我试图使用OpenSSL生成一个证书,我最终可以使用它来实例化一个新的X509EncodedKeySpec,而不会让它与InvalidKeySpecException爆炸。

到目前为止,我已尝试过以下方法:

使用OpenSSL创建密钥对:

openssl req -x509 -newkey rsa:4096 -keyout privkey.pem cert.pem -days 365

然后在我的Android应用加密类中:

/** @param rawCert is the content of cert.pem, read into a String. */
public static PublicKey regenerateKey(String rawCert) 
        throws NoSuchAlgorithmException, InvalidKeySpecException {
    KeyFactory kf = KeyFactory.getInstance("RSA");
    byte[] certBytes = Base64.decode(rawCert, 0));
    return kf.generatePublic(new X509EncodedKeySpec(certBytes));
}

证书本身如下:

-----BEGIN CERTIFICATE-----
MIIGDTCCA/WgAwIBAgIJANIT8Fk2cT0HMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
(... removed to save space in posting ...)
Fk7oUsABk7xlpP7kS5+lKfLk+/6DvwIyjU8PB6faBe8EDgXSZMh9K/36Onpvr62i
ysBiCKTT+y+NC3u4cFiTjR4=
-----END CERTIFICATE-----

为了它的价值,我已经尝试了以下实验:

  • 将原始.pem文件读入字符串(BEGIN / END CERTIFICATE和all),然后使用String的getBytes(StandardCharsets.UTF_8)方法将其转换为byte []。失败。

  • 相同的实验,但尝试使用US_ASCII和ISO_8859_1。仍然失败。

  • 删除了第一行和最后一行(因此该文件仅包含base64编码的证书内容)。失败。

  • 仔细检查以确保.pem文件没有以换行符结尾。失败。

  • base64将文件解码为byte [],而不是先前尝试使用base64编码的文件。失败。

堆栈跟踪中的特定相关行似乎是:

java.lang.RuntimeException:java.security.spec.InvalidKeySpecException:java.lang.RuntimeException:error:0c0890ba:ASN.1编码例程:asn1_check_tlen:WRONG_TAG

此时,我不确定问题是否与证书本身有关,或者是否还有其他事情(或者更确切地说)我需要做的事情就是将其按到一个表格中。是X509EncodedKeySpec可以接受的。

1 个答案:

答案 0 :(得分:1)

您使用的是错误的方法。作为点@EJP,证书包含公钥

CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
PublicKey publicKey = cert.getPublicKey();

generateCertificate()接受PEM格式的证书(带有页眉和页脚的base64)和二进制文件(删除页眉/页脚并解码base64内容)

请参阅documentation

  

对于X.509证书的证书工厂,inStream中提供的证书必须是DER编码的,并且可以二进制或可打印(Base64)编码提供。如果证书是以Base64编码提供的,那么它必须在开头由----- BEGIN CERTIFICATE -----限制,并且最后必须以----- END CERTIFICATE结束-----