java下的证书访问

X509证书的结构

我们使用java的X509Certificate类即可获得证书的信息,代码如下:

public final class CertUtil {

    public static X509Certificate certFromPath(String path) throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        try (InputStream is = new FileInputStream(path)) {
            return (X509Certificate) cf.generateCertificate(is);
        }
    }

输入文件路径,即可得到一个X509Certificate类实例,我们打印这个实例,看下其中的内容:

[
[
Version: V3
Subject: O=ABC, CN=ABC2048
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Key: Sun RSA public key, 2048 bits
modulus: 29558645527346640766137874857340082445573398292392561692082856030524889183965615877166340686232671488611789660650669998726166726306048696769263651066415583502160040748596175681126946722309295429491361358874665892735206054077011269639966943052018702613984305152754582320761458175188892443105777900976545814239980193914428631802707883805228501595666375669943084661815150812691263995160102811838239688280388520788535482369066079941347248418356552426282517933240742058190139052542638763076218614044529303735978721586502257241847506827719469054664895824920165626087958812260873444165383602754558271794400348859685786238039
public exponent: 65537
Validity: [From: Fri Aug 02 16:15:39 CST 2013,
To: Thu Jul 28 17:15:39 CST 2033]
Issuer: O=ABC, CN=ABC2048
SerialNumber: [ 7b97ca10 275a0000 0000]

Certificate Extensions: 4
……

]
Algorithm: [SHA1withRSA]
Signature:
0000: 4D DA C0 7C 5D 2F 30 AD D2 28 F7 11 B3 AA 48 48 M…]/0..(….HH
0010: F3 02 39 4E B2 CE FF 99 06 2D 20 B6 F9 42 23 93 ..9N…..- ..B#.
……

]

主要是这么几项:
+ 证书版本,一般是V3;
+ 证书持有者(Subject);
+ 签名算法(这里是SHA1withRSA,该算法会有一个固定的OID);
+ 公钥(这是最关键的,证书本质上就是公钥的载体);
+ 证书有效区间;
+ 颁发者;
+ 序列号(每个证书唯一,用于CRL中的证书失效列表);
+ 一些扩展项;
上述内容我们不妨称之为核心证书C
核心证书C后跟着证书签名,签名是用私钥对C进行摘要并加密后的内容,它起到校验证书的作用,我们知道,不对称加密体系下,公钥和私钥是一一对应的,公钥加密的内容只有私钥才能解,反之亦然。私钥是我自己持有的,我用私钥加密核心证书C的摘要得到一份签名S,然后把C+S传到对端,对端用C里的公钥+签名算法就可以解出S的明文T,接着再用公开的摘要算法对C做摘要得到T’,比较T和T’就可以判断公私钥是否匹配,从而判断我的身份。
上述过程用java代码表示是:

public void testVerify() throws Exception {
        X509Certificate dev = CertUtil.certFromPath("E:\\01study\\07Java\\certs\\dev1.cer");

        Signature sig = Signature.getInstance(dev.getSigAlgName());
        sig.initVerify(dev.getPublicKey()); //设置公钥

        //we should use getTBSCertificate NOT getEncoded, cause the later is whole file which includes signature
        sig.update(dev.getTBSCertificate()); //设置核心证书C
        boolean match = sig.verify(dev.getSignature()); //对签名做解密及比对
        if (match) {
            System.out.println("matched");
        } else {
            System.out.println("ERROR:unmatched");
        }
    }

其实,testVerify的整个过程已由X509Certificate::verify封装好了提供出来。我们这里相当于解释了一下X509Certificate::verify的原理。

身份证书和CA证书

只有身份证书是不够的,虽然能证明“我是我”,可是这个身份证书本身的可靠性又由谁来保证呢?于是就有了CA(certificate authority)这个第三方权威机构,大家只认CA签发的身份证书。
一般说来,我们会向CA申请身份证书,CA就会用CA的私钥对身份证书签名,同时CA会提供一份公钥出来,方便我们用第一章的流程来验证这个身份证书是否确实由CA签发,这个CA提供的公钥就是CA证书。因此,证书校验除了校验公私钥是否匹配,还要校验是否CA签发(当然,还有是否在CRL列表里)。

猜你喜欢

转载自blog.csdn.net/tlxamulet/article/details/77142500
今日推荐