4

我得到一个代表 PEM 证书的字符串:

-----BEGIN CERTIFICATE-----
MIICUTCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADBXMQswCQYDVQQGEwJDTjEL
MAkGA1UECBMCUE4xCzAJBgNVBAcTAkNOMQswCQYDVQQKEwJPTjELMAkGA1UECxMC
VU4xFDASBgNVBAMTC0hlcm9uZyBZYW5nMB4XDTA1MDcxNTIxMTk0N1oXDTA1MDgx
NDIxMTk0N1owVzELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlBOMQswCQYDVQQHEwJD
TjELMAkGA1UEChMCT04xCzAJBgNVBAsTAlVOMRQwEgYDVQQDEwtIZXJvbmcgWWFu
ZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCp5hnG7ogBhtlynpOS21cBewKE/B7j
V14qeyslnr26xZUsSVko36ZnhiaO/zbMOoRcKK9vEcgMtcLFuQTWDl3RAgMBAAGj
gbEwga4wHQYDVR0OBBYEFFXI70krXeQDxZgbaCQoR4jUDncEMH8GA1UdIwR4MHaA
FFXI70krXeQDxZgbaCQoR4jUDncEoVukWTBXMQswCQYDVQQGEwJDTjELMAkGA1UE
CBMCUE4xCzAJBgNVBAcTAkNOMQswCQYDVQQKEwJPTjELMAkGA1UECxMCVU4xFDAS
BgNVBAMTC0hlcm9uZyBZYW5nggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEE
BQADQQA/ugzBrjjK9jcWnDVfGHlk3icNRq0oV7Ri32z/+HQX67aRfgZu7KWdI+Ju
Wm7DCfrPNGVwFWUQOmsPue9rZBgO
-----END CERTIFICATE-----

我将上面的字符串分配给 String variable String myCertStr

转换myCertStr为 DER 编码字节 [] 的正确方法是什么?

(我正在使用 Java 7,我对为此使用 3rd 方库不感兴趣,我正在寻找一种 JDK7 的方法。)

4

1 回答 1

4

重要的

正如@dave_thompson_085 在评论中指出的那样,SunJCE CertificateFactory 确实能够解析 PEM 文件。

因此,您可以使用它来获取证书对象,详见如何从 pem 文件加载公共证书..?(这是@dave 在同一主题上的较早回答,因此,如果您觉得这很有用,请点赞它,而不是这个!),然后访问其编码 (DER) 表单。

但是,如果您的 PEM 文件是原始的“RSA PUBLIC KEY”(就像附加到这个问题的那个),或者 SunJCE 实现无法直接解析的其他实体,您仍然可以手动解析和解码它,如下详述.


从技术上讲,您在这里拥有的不是证书,而只是公钥。

您可以将其解码为 DER 字节,如下所示:

byte[] derBytes = Base64.getDecoder().decode(
    pemText.replaceAll("-----(BEGIN|END) RSA PUBLIC KEY-----", "").replaceAll("\n", "")
);

请注意,您将获得一个原始 RSA (PKCS#1) 密钥:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

您可以使用相同的技术来解码 X.509 证书或私钥。

例如解码 X.509 证书的代码:

byte[] certificateBytes = Base64.getDecoder().decode(
    pemText.replaceAll("-----(BEGIN|END) CERTIFICATE-----", "").replaceAll("\n", "").getBytes("UTF-8")
);

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate)(certificateFactory.generateCertificate(
        new ByteArrayInputStream(certificateBytes)
    )
);

更新

上面的代码使用 Java 8 Base64 解码器。由于问题已更新,要求提供 Java 7 解决方案,这里有一个优秀线程的链接,讨论了各种可用选项:Base64 Java encode and decode a string

例如,那里描述的 java.xml.bind 方法不需要 Java 7 上的任何额外库(这似乎符合 OP 的要求)

于 2016-11-05T21:10:42.557 回答