实现CRL中吊销列表按日期排序

    项目原来设计只要求读取CRL中吊销列表的序列号和吊销日期,所以并未考虑排序的问题,但是后来又要求按照吊销日期进行排序。

    下面是原来的程序,显示出来的吊销列表顺序是乱的,和证书上的顺序不一致。

 

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509CRL crl = (X509CRL)cf.generateCRL(new FileInputStream("c:\\1.crl"));
//读取版本号
int version = crl.getVersion();
//读取颁发者DN
String issuerDN = crl.getIssuerDN().toString();
//读取生效日期
Date startTime = crl.getThisUpdate();
//读取下一次更新日期
Date nextUpdateTime = crl.getNextUpdate();
//读取吊销列表
Set tSet = crl.getRevokedCertificates();
Iterator tIterator = tSet.iterator();
while(tIterator.hasNext()){
    X509CRLEntry tEntry = (X509CRLEntry) tIterator.next();
    //读取序列号
    String sn = getSerialNumber(tEntry);
    //读取吊销日期
    String time = tEntry.getRevocationDate().toLocaleString();
}

 

    根据吊销列表中的每个对象获得序列号的字符串值,entry.getSeriaNumber()读取出来是BigInteger,可读性不好也不直观,所以下面的方法将其转换成字符串,并且和证书上显示的序列号相同。

 

public static String getSerialNumber(X509CRLEntry entry){
    if(entry != null){
        byte[] serial = entry.getSerialNumber().toByteArray();
        if(serial.length>0){
            String serialNumberString = new String();
            for(int i=0;i<serial.length;i++){
                String s =Integer.toHexString(Byte.valueOf(serial[i]).intValue());
                if(s.length()==8){
                    s = s.substring(6);
                }else if(1==s.length()){
                    s="0"+s;
                }
                serialNumberString+=s+" ";
            }
            return serialNumberString;
        }
    }
    return null;
}

 

    现在要对集合进行排序,需要实现Comparator类的compare方法,当吊销日期相同时按照序列号自然排序。

    注意:排序方法很重要,如果只比较吊销日期,不做compare==0判断的话,使用第一种方法即TreeSet,最后输出结果可能有误,会导致丢失吊销证书信息的情况。因为TreeSet基于Set接口,虽然可以排序,但是仍然不允许元素重复。第二种方法即List接口允许元素重复,所以不会出现这种情况。

 

public class CRLDateComparator implements Comparator {
	
    public int compare(Object o1, Object o2){
        X509CRLEntry entry1 = (X509CRLEntry)o1;
        X509CRLEntry entry2 = (X509CRLEntry)o2;
        int compare = entry1.getRevocationDate().compareTo(entry2.getRevocationDate());
        if(compare == 0){
            String sn1 = getSerialNumber(entry1);
            String sn2 = getSerialNumber(entry2);
            compare = sn1.compareTo(sn2);
        }
        return compare;
}

  

    实现方法有2种:TreeSet和List。

    第一种 TreeSet 

 

Set tSet = crl.getRevokedCertificates();

//----------加入代码开始----------
TreeSet ts = new TreeSet(new CRLDateComparator());
ts.addAll(set);
//----------加入代码结束----------

Iterator tIterator = ts.iterator();

 

    第二种 List 

 

Set tSet = crl.getRevokedCertificates();

//----------加入代码开始----------
List l = new ArrayList();
l.addAll(set);
Collections.sort(l, new CRLDateComparator());
//----------加入代码结束----------

Iterator tIterator = l.iterator();

 

    以上两种方法经过测试,都可以满足要求。

你可能感兴趣的:(排序)