我尝试在 java中解析证书的额外数据。我对 subjectAlternativeNames 部分感兴趣。我的代码是:
CertificateFactory certFactory = CertificateFactory.getInstance("X.509")
certFactory.generateCertificate(ByteArrayInputStream(x509EntryChain.leafCertificate))
X509CertInfo
包含java.io.IOException: invalid URI name:DNS:*.cetrel.lu, DNS:mail.cetrel.lu, DNS:www.cetrel.lu
. 并且subjectAlternativeNames
是空的。
我该如何解析它?
我只对 感兴趣extra_data
,对 不感兴趣leaf_input
。我可以在这里找到证书:http: //transparencyreport.google.com/https/certificates/
该DNS names
部分是空的,似乎谷歌也无法解析它。
提供证书的完整代码:
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.security.x509.CertificateExtensions;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
public class CertParser {
public static void main(String[] args) throws CertificateException, IOException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(
"AAAAAAFXsGq8HwAAAAW+MIIFujCCBKKgAwIBAgIDAZZpMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkxVMRYwFAYDVQQKEw1MdXhUcnVzdCBTLkEuMR4wHAYDVQQDExVMdXhUcnVzdCBRdWFsaWZpZWQgQ0EwHhcNMTAwNDE1MDY0MzM0WhcNMTMwNDE1MDY0MzM0WjB8MQswCQYDVQQGEwJMVTERMA8GA1UEBxMITXVuc2JhY2gxFDASBgNVBAoTC0NFVFJFTCBTLkEuMRAwDgYDVQQLEwdJT1AtU1NTMRQwEgYDVQQDFAsqLmNldHJlbC5sdTEcMBoGCSqGSIb3DQEJARYNc3NzQGNldHJlbC5sdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALhf+I7RshQlHMMWq/WPDLNxx+ODMd4Tn9ej14igvMEE+RYEagdMOZoeO8Bqz9qV2atzFHqz0D+Ad+cxuznBGKl4rhS9gUejgoAMox7car0+LSsv1NT4J0gAlnmH3BJlDMd9CihT0D/sRwMNfa8GYAvCuGDtWIvYb497RFy+2kmzk3cwCk3BgOO3MsT7iqhcn65Pd1Lq1vLjCCuQBoWLlcKk4uptPsyFKrHEh1/0ksY5evqBPxioVppoN+oay20RK36JzrzAl+vfpzq03WRlM2IgM0ItnesLqid9GqTUsOTq59i5aVX1EKlfgM5v7YCpYMLrJA+JBO3beR/4FSczfccCAwEAAaOCAnowggJ2MAwGA1UdEwEB/wQCMAAwYAYIKwYBBQUHAQEEVDBSMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5sdXh0cnVzdC5sdTArBggrBgEFBQcwAoYfaHR0cDovL2NhLmx1eHRydXN0Lmx1L0xUUUNBLmNydDBBBgNVHREEOjA4hjZETlM6Ki5jZXRyZWwubHUsIEROUzptYWlsLmNldHJlbC5sdSwgRE5TOnd3dy5jZXRyZWwubHUwggEABgNVHSAEgfgwgfUwgegGCCuBKwEBAgYBMIHbMIGtBggrBgEFBQcCAjCBoBqBnUx1eFRydXN0IFNlcnZlciBDZXJ0aWZpY2F0ZS4gTm90IHN1cHBvcnRlZCBieSBTU0NELCBLZXkgR2VuZXJhdGlvbiBieSBTdWJzY3JpYmVyLiBHVEMsIENQIGFuZCBDUFMgb24gaHR0cDovL3JlcG9zaXRvcnkubHV4dHJ1c3QubHUuIFNpZ25lZCBieSBhIFF1YWxpZmllZCBDQS4wKQYIKwYBBQUHAgEWHWh0dHA6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0Lmx1MAgGBgQAj3oBAzARBglghkgBhvhCAQEEBAMCBeAwDgYDVR0PAQH/BAQDAgSwMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwQwHwYDVR0jBBgwFoAUjZCjB90aE3eZTJKrTUPeP80pZAUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5sdXh0cnVzdC5sdS9MVFFDQS5jcmwwHQYDVR0OBBYEFLhOdzNJg4CSchxSsHbwKWMVm8xnMA0GCSqGSIb3DQEBBQUAA4IBAQBrQ9bYRA5O8a+4vIfVx5izH5x9yieKuQjpF4Etc4YUxfk3h5yZieWJuZGHygUjV5TCYDdhtVf6FFWkJ4FT5l6zDQeOLrEWqL12qcT4hGFN61mwjZO7kca8IHlqPPeqtYVg/Ssbpun+bjPOsGdvrvMulqNNTz5UeQuovc/VFaoHpYCQhezrQ6E6uQ684f6LFVIbsah6pT58wEnrf6xE1aRdSk27e3bF8wns3zOVsWE2wKck5pMS5DkGwjWli27Aqt6QQCyCKC7xqqxwL8GfnmXZNdn2iYYfSyr0I7rdqxa7FsuNFkEb8/PdZlyMxQP867YnucRCyLzzjCnRy1bOLnUeAAA="
));
readNumber(in, 1); // version
readNumber(in, 1); // type
readNumber(in, 8); // timestamp
readNumber(in, 2); // entry type
int length = (int) readNumber(in, 3);
byte[] x509 = readFixedLength(in, length);
X509CertImpl cert = (X509CertImpl) certFactory.generateCertificate(new ByteArrayInputStream(x509));
((CertificateExtensions)((X509CertInfo)cert.get("x509.info")).get("extensions")).getUnparseableExtensions(); // <-- want too be empty, but it's not!!!
}
static byte[] readFixedLength(InputStream inputStream, int dataLength) throws IOException {
byte[] toReturn = new byte[dataLength];
int bytesRead = inputStream.read(toReturn);
if (bytesRead < dataLength) {
throw new RuntimeException();
}
return toReturn;
}
static long readNumber(InputStream inputStream, int numBytes) throws IOException {
long toReturn = 0;
for (int i = 0; i < numBytes; i++) {
int valRead = inputStream.read();
if (valRead < 0) {
throw new RuntimeException();
}
toReturn = (toReturn << 8) | valRead;
}
return toReturn;
}
}