我试图使用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可以接受的。
答案 0 :(得分:1)
您使用的是错误的方法。作为点@EJP,证书包含公钥
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
PublicKey publicKey = cert.getPublicKey();
generateCertificate()
接受PEM格式的证书(带有页眉和页脚的base64)和二进制文件(删除页眉/页脚并解码base64内容)
对于X.509证书的证书工厂,inStream中提供的证书必须是DER编码的,并且可以二进制或可打印(Base64)编码提供。如果证书是以Base64编码提供的,那么它必须在开头由----- BEGIN CERTIFICATE -----限制,并且最后必须以----- END CERTIFICATE结束-----