从 XAdES-X-L 中获取证书
import java.io.ByteArrayInputStream; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import xades4j.properties.CertificateValuesProperty; import xades4j.properties.QualifyingProperty; public class XAdESXLUtil { public static List<X509Certificate> getCerts(Document xadesxlDoc) { if (xadesxlDoc == null) { return null; } NodeList nodeList = xadesxlDoc.getElementsByTagNameNS(QualifyingProperty.XADES_XMLNS, CertificateValuesProperty.PROP_NAME); if (nodeList.getLength() != 1) { return null; } CertificateFactory cf = null; try { cf = CertificateFactory.getInstance("X.509", "BC"); } catch (Exception e1) { e1.printStackTrace(); return null; } List<X509Certificate> certList = new ArrayList<X509Certificate>(); Node certificateValues = nodeList.item(0); NodeList encapsulatedX509Certificates = certificateValues.getChildNodes(); for (int i = 0; i < encapsulatedX509Certificates.getLength(); i++) { Node item = encapsulatedX509Certificates.item(i); String textContent = item.getTextContent(); ByteArrayInputStream bis = new ByteArrayInputStream( ("-----BEGIN CERTIFICATE-----\r\n" + textContent + "\r\n-----END CERTIFICATE-----").getBytes()); X509Certificate c; try { c = (X509Certificate) cf.generateCertificate(bis); certList.add(c); } catch (CertificateException e) { e.printStackTrace(); } } return certList; } }
关键点:
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-----.
Open Declaration Certificate java.security.cert.CertificateFactory.generateCertificate(InputStream inStream) throws CertificateException Generates a certificate object and initializes it with the data read from the input stream inStream. In order to take advantage of the specialized certificate format supported by this certificate factory, the returned certificate object can be typecast to the corresponding certificate class. For example, if this certificate factory implements X.509 certificates, the returned certificate object can be typecast to the X509Certificate class. 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-----. Note that if the given input stream does not support mark and reset, this method will consume the entire input stream. Otherwise, each call to this method consumes one certificate and the read position of the input stream is positioned to the next available byte after the inherent end-of-certificate marker. If the data in the input stream does not contain an inherent end-of-certificate marker (other than EOF) and there is trailing data after the certificate is parsed, a CertificateException is thrown. Parameters: inStream an input stream with the certificate data. Returns: a certificate object initialized with the data from the input stream. Throws: CertificateException - on parsing errors.
证书例子:
<xades:EncapsulatedX509Certificate>MIIFxDCCBKygAwIBAgIKEOFSkgAAAAGSxDANBgkqhkiG9w0BAQUFADCB2zELMAkGA1UEBhMCSVIx FTATBgNVBAoTDEdvdmVybm1lbnRhbDEvMC0GA1UECxMmSXJhbiBDZW50ZXIgZm9yIGUtQ29tbWVy Y2UgRGV2ZWxvcG1lbnQxOjA4BgNVBAsTMURlcHV0eSBvZiBQS0kgYW5kIENvbW1lcmNpYWwgSW5m b3JtYXRpb24gU2VjdXJpdHkxIDAeBgNVBAsTF0dlbmVyYWwgSW50ZXJtZWRpYXRlIENBMSYwJAYD VQQDEx1HSUNBIERpZ2l0YWwgU2lnbiBTaWx2ZXIgTm8uNTAeFw0xNzAxMTgwNzUzNDJaFw0xODAx MTgwNzUzNDJaMIHOMQswCQYDVQQGEwJJUjETMBEGA1UECAwK2KrZh9ix2KfZhjETMBEGA1UEBwwK 2KrZh9ix2KfZhjEVMBMGA1UEChMMVW5hZmZpbGlhdGVkMSQwIgYDVQQLExtJbmRpdmlkdWFsIExl dmVsIDIgKFNpbHZlcikxEzARBgNVBAUTCjEyOTI4Mjg5NTExETAPBgNVBCoMCNmF2K3ZhdivMRUw EwYDVQQEDAzZhdmH2LHYstin2K8xGTAXBgNVBAMTEE1vaGFtbWFkIE1laHJ6YWQwgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAK0rP1xKkSQ4XhtA+TrYnmRS3Qp/8YVYG2dV3HQD8pq5aAxmeWb2 gZwCLOCpv/orut8fNOzbUh4MRWCPmEjMJTUTc0XO67bsw2PLQPm9TavN/HQWeAjZVgBHeoHSzf/0 sC/yWaCqLEiPQz1ST7o9v5ZrUZ8Ht4W4lIHhaev/+rbLAgMBAAGjggIXMIICEzAOBgNVHQ8BAf8E BAMCBsAwHQYDVR0OBBYEFCWKnRlu22wlOCwVGyJl7wtBuyKYMCsGA1UdJQQkMCIGCisGAQQBgjcU AgIGCisGAQQBgjcKAwwGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFDeoHLs9mut/wKPAN2sWO6e8BqHZ MEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuZ2ljYS5pci9yZXBvc2l0b3J5L0RTL0RTLVNp bHZlci1Oby41LmNybDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdp Y2EuaXIvb2NzcDCB3gYDVR0gBIHWMIHTMEUGCWCCbGUBAQECAjA4MDYGCCsGAQUFBwIBFipodHRw Oi8vd3d3LmdpY2EuaXIvcmVwb3NpdG9yeS9jcHMtZ2ljYS5wZGYwRQYJYIJsZQEBAwICMDgwNgYI KwYBBQUHAgEWKmh0dHA6Ly93d3cuZ2ljYS5pci9yZXBvc2l0b3J5L2Nwcy1naWNhLnBkZjBDBgdg gmxlAQMBMDgwNgYIKwYBBQUHAgEWKmh0dHA6Ly93d3cuZ2ljYS5pci9yZXBvc2l0b3J5L2Nwcy1n aWNhLnBkZjA3BgkrBgEEAYI3FQoEKjAoMAwGCisGAQQBgjcUAgIwDAYKKwYBBAGCNwoDDDAKBggr BgEFBQcDAjANBgkqhkiG9w0BAQUFAAOCAQEANke02azEjpxHBPRNfhO85rKbe7JDdJla33iNW9pA 5ar0GFFAtsw/0bNv4abHf7AxVpBiSwzMxA/y2UzDUabKd/adwnvG5FyzPM5FwCHEmZ1ZNa2IREs7 zvJnPsaAAygIqyvEWdJsylHqT3G5zUqV5eAvXS3qgjYGEYb+5/0G3bUH5jsjGCQzhhw2enfOYYm3 9D6SBWrgm5OGSyCo2/8SuTJzapqxHvQjhuRcrKkhRYtOmqGiAkPSTj1fY/jB/sN+O3shVo5QBddi si6oVoERRP/04uoh+tTCRdfd9EwGwuZWk2YydthzhZDOcvwdf4RMlRq7bCpZDMwAJkuAJeusXA==</xades:EncapsulatedX509Certificate>