在Java中检索X.509证书的使用者替代名称 [英] Retrieve Subject alternative names of X.509 certificate in java

查看:60
本文介绍了在Java中检索X.509证书的使用者替代名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用此链接中提供的解决方案.

I have tried using the solution provided in this link.

当我尝试读取X.509证书的使用者替代名称时,出现以下错误

I am getting following error when i tried reading subject alternative names of X.509 Certificate

java.lang.NoSuchMethodError:org.bouncycastle.asn1.ASN1InputStream.readObject()Lorg/bouncycastle/asn1/DERObject;

java.lang.NoSuchMethodError: org.bouncycastle.asn1.ASN1InputStream.readObject()Lorg/bouncycastle/asn1/DERObject;

在下面的代码行

ASN1InputStream解码器=新的ASN1InputStream((byte [])item.toArray());

ASN1InputStream decoder = new ASN1InputStream((byte[]) item.toArray());

DEREncodable编码= coder.readObject();

DEREncodable encoded = decoder.readObject();

.der文件用于创建证书,如下所示.

.der file is used to create certificate as follows.

X509Certificate cert=null;
fis = new FileInputStream(file.getAbsoluteFile());     //.der file
bis = new BufferedInputStream(fis);

CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
                    try{
                    cert = cf.generateCertificate(bis);
                    }
                     catch (CertificateException e) {
                      e.printStackTrace();
                  }
 List list=getSubjectAlternativeNames((X509Certificate) cert);

下面是我从上面提到的链接中获得的解决方案.

Below is the solution i got from the link mentioned above.

   public static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
    List<String> identities = new ArrayList<String>();
    try {
        Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
        // Check that the certificate includes the SubjectAltName extension
        if (altNames == null)
            return Collections.emptyList();
        // Use the type OtherName to search for the certified server name
        for (List item : altNames) {
            Integer type = (Integer) item.get(0);
            if (type == 0)
                // Type OtherName found so return the associated value
                try {
                    // Value is encoded using ASN.1 so decode it to get the server's identity
                    ASN1InputStream decoder = new ASN1InputStream((byte[]) item.toArray()[1]);
                    DEREncodable encoded = decoder.readObject();
                    encoded = ((DERSequence) encoded).getObjectAt(1);
                    encoded = ((DERTaggedObject) encoded).getObject();
                    encoded = ((DERTaggedObject) encoded).getObject();
                    String identity = ((DERUTF8String) encoded).getString();
                    // Add the decoded server name to the list of identities
                    identities.add(identity);
                }
            catch (UnsupportedEncodingException e) {
                e.printStackTrace();
               // log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
            }
            catch (Exception e) {
               // log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
                e.printStackTrace();
            }
            // Other types are not good for XMPP so ignore them
            //log.warn("SubjectAltName of invalid type found: " + certificate);
        }
    }
    catch (CertificateParsingException e) {
        e.printStackTrace();
       // log.error("Error parsing SubjectAltName in certificate: " + certificate + "\r\nerror:" + e.getLocalizedMessage(),e);
    }
    return identities;
}

是不是我没有使用正确的.jar文件?

Is it that i have not used proper .jar file?

.jar是->bcprov-jdk16-1.45.jar

.jar i have used is --> bcprov-jdk16-1.45.jar

建议我哪里出了问题.

推荐答案

我尝试使用您的代码以使其正常运行,并使用从Internet Explorer导出的证书进行了测试

I tried with your code for me it is working, I tested with a certificate exported from internet explorer

Internet Explorer -> Tools -> Internet Options -> Content -> Certificates -> Untrusted Publishers -> www.google.com

我将其导出为".cer",对您的代码进行了很少的更改

I exported this as ".cer", I made few changes to your code

public static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
        List<String> identities = new ArrayList<String>();
        try {
            Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
            if (altNames == null)
                return Collections.emptyList();
            for (List item : altNames) {
                Integer type = (Integer) item.get(0);
                if (type == 0 || type == 2){
                    try {
                        ASN1InputStream decoder=null;
                        if(item.toArray()[1] instanceof byte[])
                            decoder = new ASN1InputStream((byte[]) item.toArray()[1]);
                        else if(item.toArray()[1] instanceof String)
                            identities.add( (String) item.toArray()[1] );
                        if(decoder==null) continue;
                        DEREncodable encoded = decoder.readObject();
                        encoded = ((DERSequence) encoded).getObjectAt(1);
                        encoded = ((DERTaggedObject) encoded).getObject();
                        encoded = ((DERTaggedObject) encoded).getObject();
                        String identity = ((DERUTF8String) encoded).getString();
                        identities.add(identity);
                    }
                    catch (UnsupportedEncodingException e) {
                        log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
                    }
                    catch (Exception e) {
                        log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
                    }
                }else{
                    log.warn("SubjectAltName of invalid type found: " + certificate);
                }
            }
        }
        catch (CertificateParsingException e) {
            log.error("Error parsing SubjectAltName in certificate: " + certificate + "\r\nerror:" + e.getLocalizedMessage(),e);
        }
        return identities;
    }

我将文件保存到c:\ aa1.cer

I saved the file to c:\aa1.cer

X509Certificate cert=null;
        FileInputStream fis = new FileInputStream("c:\\aa1.cer");
        BufferedInputStream bis = new BufferedInputStream(fis);

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        if (bis.available() > 0)
            try{
               cert = (X509Certificate)cf.generateCertificate(bis);
            }
            catch (CertificateException e) {
                e.printStackTrace();
            }
        System.out.println(CertificateInfo.getSubjectAlternativeNames(cert));

我得到的输出为[www.google.com,google.com]

I got the output as [www.google.com, google.com]

请检查您的证书,我认为问题是您的证书

Please check your certificate, I think the problem is your certificate

这篇关于在Java中检索X.509证书的使用者替代名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆