如何生成 X509EncodedKeySpec 的构造函数可接受的 X509 证书?
How to generate X509 cert that's acceptable to X509EncodedKeySpec's constructor?
我正在尝试使用 OpenSSL 生成一个证书,我最终可以使用它来实例化一个新的 X509EncodedKeySpec,而不会因 InvalidKeySpecException 而崩溃。
到目前为止,我已经尝试了以下方法:
使用 OpenSSL 创建了密钥对:
openssl req -x509 -newkey rsa:4096 -keyout privkey.pem cert.pem -days 365
然后在我的 Android 应用的加密中 class:
/** @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 和所有),然后使用字符串的 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编码routines:asn1_check_tlen:WRONG_TAG
在这一点上,我不确定问题是出在证书本身上,还是我需要做其他事情(或相反)将其修改为 X509EncodedKeySpec 可接受的形式。
你用错了方法。作为点@EJP,证书包含一个 public 密钥
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
PublicKey publicKey = cert.getPublicKey();
generateCertificate()
接受 PEM 格式(带页眉和页脚的 base64)和二进制(删除 header/footer 并解码 base64 内容)的证书
In the case of a certificate factory for X.509 certificates, the certificate provided in inStream must be DER-encoded and may be supplied in binary or printable (Base64) encoding. If the certificate is provided in Base64 encoding, it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at the end by -----END CERTIFICATE-----.
我正在尝试使用 OpenSSL 生成一个证书,我最终可以使用它来实例化一个新的 X509EncodedKeySpec,而不会因 InvalidKeySpecException 而崩溃。
到目前为止,我已经尝试了以下方法:
使用 OpenSSL 创建了密钥对:
openssl req -x509 -newkey rsa:4096 -keyout privkey.pem cert.pem -days 365
然后在我的 Android 应用的加密中 class:
/** @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 和所有),然后使用字符串的 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编码routines:asn1_check_tlen:WRONG_TAG
在这一点上,我不确定问题是出在证书本身上,还是我需要做其他事情(或相反)将其修改为 X509EncodedKeySpec 可接受的形式。
你用错了方法。作为点@EJP,证书包含一个 public 密钥
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
PublicKey publicKey = cert.getPublicKey();
generateCertificate()
接受 PEM 格式(带页眉和页脚的 base64)和二进制(删除 header/footer 并解码 base64 内容)的证书
In the case of a certificate factory for X.509 certificates, the certificate provided in inStream must be DER-encoded and may be supplied in binary or printable (Base64) encoding. If the certificate is provided in Base64 encoding, it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at the end by -----END CERTIFICATE-----.