将证书文件加载到证书对象中。

3
我正在尝试将证书文件加载到证书对象中,但却遇到了以下异常。
    java.security.cert.CertificateParsingException: invalid DER-encoded certificate data
    at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1701)
    at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:303)
    at sun.security.provider.X509Factory.parseX509orPKCS7Cert(X509Factory.java:532)
    at sun.security.provider.X509Factory.engineGenerateCertificates(X509Factory.java:417)
    at java.security.cert.CertificateFactory.generateCertificates(CertificateFactory.java:427)

以下是我正在使用的代码来读取证书文件,
    final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    final Collection<? extends Certificate> certs =
         (Collection<? extends Certificate>) certFactory.generateCertificates(new ByteArrayInputStream(FileUtils.readFileToByteArray(serverCertFile)));

以下是证书文件的内容,
Certificate:
Data:
    Version: 3 (0x2)
    Serial Number:
        c1:cb:80:07:27:ce:4b:62
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: C=qw, ST=ewe, L=rew, O=rwerwe, OU=rwer, CN=rew/emailAddress=rewrew
    Validity
        Not Before: Jan 28 06:17:34 2013 GMT
        Not After : Feb 27 06:17:34 2013 GMT
    Subject: C=qw, ST=ewe, L=rew, O=rwerwe, OU=rwer, CN=rew/emailAddress=rewrew
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
        RSA Public Key: (1024 bit)
            Modulus (1024 bit):
                00:b6:d5:fd:01:2b:6d:ab:e2:da:a9:b4:a9:67:48:
                ce:72:d9:15:de:66:22:8e:68:a8:7b:7e:55:06:97:
                56:d2:bd:6a:2e:04:89:df:6a:36:9e:3d:ba:fc:32:
                b2:8b:f0:69:5d:54:54:b6:3e:b5:55:38:89:1f:1c:
                d0:4b:21:de:76:b3:be:fc:41:b5:62:b8:b8:3b:dc:
                ad:6d:e1:fc:1c:56:6d:90:1a:b3:6c:57:7e:66:a0:
                07:b9:16:99:cc:d4:c9:ee:05:7c:9d:1c:fb:6b:8f:
                a3:4b:d6:1c:a9:aa:51:e1:41:0d:10:a9:fe:b6:1b:
                f0:33:0c:ea:52:b9:9b:8e:5d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Key Identifier: 
            FF:24:75:B1:32:C2:74:6D:B4:CB:22:A9:92:CF:F4:B6:4A:5F:0B:56
        X509v3 Authority Key Identifier: 
            keyid:FF:24:75:B1:32:C2:74:6D:B4:CB:22:A9:92:CF:F4:B6:4A:5F:0B:56
            DirName:/C=qw/ST=ewe/L=rew/O=rwerwe/OU=rwer/CN=rew/emailAddress=rewrew
            serial:C1:CB:80:07:27:CE:4B:62

        X509v3 Basic Constraints: 
            CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
    46:14:65:27:c2:cd:55:ba:b4:0f:92:ac:8c:e4:bd:e5:e5:8d:
    e3:3b:59:52:9b:40:6a:dc:e3:cf:2c:03:49:e4:56:33:88:f6:
    94:10:de:64:00:2e:c6:2a:13:98:d0:16:71:25:8a:ea:04:3f:
    14:af:bf:8d:e1:7f:aa:54:78:68:32:86:67:9d:1d:42:fc:cb:
    1d:f2:7c:0b:1d:24:2f:e5:3f:bd:01:bd:d7:2d:74:4a:e9:7b:
    2f:25:97:64:7e:10:ba:bf:dd:49:6d:8a:91:e4:50:d8:a3:04:
    cc:37:8c:45:bd:13:b7:88:72:ef:24:20:b1:aa:05:6c:37:36:
    05:c6
    -----BEGIN CERTIFICATE-----
    MIIDLjCCApegAwIBAgIJAMHLgAcnzktiMA0GCSqGSIb3DQEBBQUAMG4xCzAJBgNV
    BAYTAnF3MQwwCgYDVQQIEwNld2UxDDAKBgNVBAcTA3JldzEPMA0GA1UEChMGcndl
    cndlMQ0wCwYDVQQLEwRyd2VyMQwwCgYDVQQDEwNyZXcxFTATBgkqhkiG9w0BCQEW
    BnJld3JldzAeFw0xMzAxMjgwNjE3MzRaFw0xMzAyMjcwNjE3MzRaMG4xCzAJBgNV
    BAYTAnF3MQwwCgYDVQQIEwNld2UxDDAKBgNVBAcTA3JldzEPMA0GA1UEChMGcndl
    cndlMQ0wCwYDVQQLEwRyd2VyMQwwCgYDVQQDEwNyZXcxFTATBgkqhkiG9w0BCQEW
    BnJld3JldzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAttX9ASttq+LaqbSp
    Z0jOctkV3mYijmioe35VBpdW0r1qLgSJ32o2nj26/DKyi/BpXVRUtj61VTiJHxzQ
    SyHedrO+/EG1Yri4O9ytbeH8HFZtkBqzbFd+ZqAHuRaZzNTJ7gV8nRz7a4+jS9Yc
    qapR4UENEKn+thvwMwzqUrmbjl0CAwEAAaOB0zCB0DAdBgNVHQ4EFgQU/yR1sTLC
    dG20yyKpks/0tkpfC1YwgaAGA1UdIwSBmDCBlYAU/yR1sTLCdG20yyKpks/0tkpf
    C1ahcqRwMG4xCzAJBgNVBAYTAnF3MQwwCgYDVQQIEwNld2UxDDAKBgNVBAcTA3Jl
    dzEPMA0GA1UEChMGcndlcndlMQ0wCwYDVQQLEwRyd2VyMQwwCgYDVQQDEwNyZXcx
    FTATBgkqhkiG9w0BCQEWBnJld3Jld4IJAMHLgAcnzktiMAwGA1UdEwQFMAMBAf8w
    DQYJKoZIhvcNAQEFBQADgYEARhRlJ8LNVbq0D5KsjOS95eWN4ztZUptAatzjzywD
    SeRWM4j2lBDeZAAuxioTmNAWcSWK6gQ/FK+/jeF/qlR4aDKGZ50dQvzLHfJ8Cx0k
    L+U/vQG91y10Sul7LyWXZH4Qur/dSW2KkeRQ2KMEzDeMRb0Tt4hy7yQgsaoFbDc2
    BcY=
    -----END CERTIFICATE-----

如果我使用相同的代码,并将证书文件中从顶部到“BEGIN CERTIFICATE”的内容删除,则可以正常工作。但我的要求是证书文件将拥有这些内容。是否有人遇到过这个错误?任何帮助将不胜感激。
2个回答

2
问题在于,只有在 PEM 格式的证书以 -----BEGIN CERTIFICATE----- 开头时,CertificateFactory 才会读取它。一些工具会在开头添加额外信息(例如 openssl x509 -text 的结果),但是证书工厂不会忽略它并将其视为格式错误的证书。

相反,使用 BuffedReaderreadLine()来读取文件,忽略任何行,直到遇到 -----BEGIN CERTIFICATE-----。然后,将所有行添加到临时字符串变量(或类似变量,例如 StringBuilder)中,直到遇到 -----END CERTIFICATE----- 为止。将此传递给 CertificateFactory


1
请注意,从Java 7开始,CertificateFactory可以正确处理注释头。但是它不支持缩进的证书块。 - Emmanuel Bourg

1
我觉得你的证书文件可能不是正确的格式。 CertificateFactory.generateCertificates文档中写道:
在X.509证书工厂的情况下,inStream中提供的证书必须是DER编码的,可以以二进制或可打印(Base64)编码形式提供。如果证书以Base64编码形式提供,则必须在开头加上-----BEGIN CERTIFICATE-----,在结尾处加上-----END CERTIFICATE-----。
我不认为问题就像简单地向现有证书添加边界标记那样解决。
我只用过PEM格式,它是base-64编码的DER格式,所以我不确定你的格式是否正确,但我猜测二进制DER编码的证书不是人类可读的文本。
因此,我建议你回到源证书,并确保获得具有正确格式的副本。如果原始证书有不同的格式,你可以使用openssl将其转换为pem格式。

1
如果您查看问题中的示例,边界标记已经存在(如果向下滚动,则在末尾)。CertificateFactory只是无法处理标记之前的内容。 - Bruno
是的,你说得对 - 我没有向下滚动。所以,我尝试使用openssl解码证书 - 除非这是一个复制粘贴错误,问题在于标记不是从第一列开始的 - 删除开始和结束标记前面的四个空格,然后它就可以成功解码了。 - GreyBeardedGeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接