ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java实现解析x509数字证书DN的各项属性,并校验DN是否符合标准

2021-03-02 15:02:20  阅读:436  来源: 互联网

标签:DN x500 bouncycastle x509 asn1 org java 属性


目录


前言

公司产品中一个业务需要解析证书DN的各项属性,并提取某项属性的属性值。之前的实现是将DN作为字符串进行操作,以逗号split之后遍历取出各项属性,再以等号split取出某项属性值。在碰到某个DN中有一个逗号(,)的特殊格式后就会导致数组越界的问题。这种方式很不可取,遂查资料写了以下两种方式。


一、使用 javax.naming.ldap.LdapName 类

		LdapName ln = null;
        try {
            ln = new LdapName(dn);
        } catch (InvalidNameException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for(Rdn rdn : ln.getRdns()) {
            System.out.println("LdapName--Type-- "+rdn.getType());
            System.out.println("LdapName--Value-- "+rdn.getValue());
        }

这个方法是在网上查到,容易实现,不用引入其他jar包,是java自带的方法。符合RFC 2253规定的,类似于CN = Steve Kille,O = Isode Limited,C = CN这种格式的字符串都能解析。但在这个业务场景下,该方法的缺点是不能判断某个属性是否是证书DN中规定的属性。比如CNTest = Steve Kille,O = Isode Limited,C = CN,标准的证书DN项中没有CNTest 这一项,但是这种方法同样可以解析出来。

二、使用 org.bouncycastle.asn1.x500.X500Name 类(推荐)

基于以上原因,考虑到产品中的实际业务使用,翻阅bouncycastle的源码,写了如下方法。

maven引入

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.51</version>
        </dependency>

代码如下

	private static Map<String, String> parseDNToMap(String dn) {
        
        if(StrUtil.isBlank(dn)) {
            return null;
        }
        
        Map<String, String> resMap = new HashMap<String, String>();
        
        X500Name x500Name = new X500Name(dn);
        
        RDN[] rdNs = x500Name.getRDNs();
        for (int i = 0; i < rdNs.length; i++) {
            
            AttributeTypeAndValue first = rdNs[i].getFirst();
			//获取属性名的oid
            ASN1ObjectIdentifier type = first.getType();
            
            //将属性名的oid转换为属性名
            String typeString = BCStyle.INSTANCE.oidToDisplayName(type).toUpperCase();
            //或使用RFC4519Style.INSTANCE.oidToDisplayName(type).toUpperCase();
            
            //获取属性值
            String valueString = first.getValue().toString();
            
            resMap.put(typeString, valueString);
        }
        
        return resMap;
    }

如果有非标准规定的属性名,会抛出异常如下

Exception in thread "main" java.lang.IllegalArgumentException: Unknown object id - CNTest - passed to distinguished name
	at org.bouncycastle.asn1.x500.style.IETFUtils.decodeAttrName(Unknown Source)
	at org.bouncycastle.asn1.x500.style.BCStyle.attrNameToOID(Unknown Source)
	at org.bouncycastle.asn1.x500.style.IETFUtils.rDNsFromString(Unknown Source)
	at org.bouncycastle.asn1.x500.style.BCStyle.fromString(Unknown Source)
	at org.bouncycastle.asn1.x500.X500Name.<init>(Unknown Source)
	at org.bouncycastle.asn1.x500.X500Name.<init>(Unknown Source)
	at com.certTest.x509NameTest.main(x509NameTest.java:86)


总结

以上两种方法亲测有效,如果只是要解析DN各项,第一种方法更方便。如果同时需要校验DN是否符合标准可选用第二种。

标签:DN,x500,bouncycastle,x509,asn1,org,java,属性
来源: https://blog.csdn.net/weixin_36998210/article/details/114281692

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有