密码学研究-证书

引入:

在密码学中,证书是一个非常重要的概念,我这里不想展开了, 通常的证书都是基于X.509规范的,有兴趣的同学可以去看对应介绍:

实践:

其实证书无处不在,我们的浏览器里面一般都会可以看到一些证书,有些是自动添加进去的,有些可以手动添加进去,比如我自己机器上用Chrome:在chrome://settings/advanced里面

你往下看到HTTPS/SSL ,,点击Manage Certificates…按钮: 就会看出被管理的证书列表:

我们选出其中某个证书,比如Alibaba.com,然后导出到本地,然后用java提供的Certificate类来分析这个证书。

为了分析证书,我们写了一个工具类:

package com.charles.certificatestudy;import java.io.FileInputStream;import java.math.BigInteger;import java.security.PublicKey;import java.security.cert.CRL;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.util.Date;import javax.security.auth.x500.X500Principal;import sun.misc.BASE64Encoder;/** * * Description: 这个工具类提供了证书的一般操作 * * @author charles.wang * @created Oct 29, 2013 2:57:58 PM * */public class CertificateUtil {public static X509Certificate getX509certFromCertificatePath(String certificateName) throws Exception{CertificateFactory certificateFactory = CertificateFactory.getInstance(“X.509”);// 获得证书文件的输入流FileInputStream in = new FileInputStream(certificateName);// 获得证书Certificate certificate = certificateFactory.generateCertificate(in);// 获取证书的类型String certType = certificate.getType();System.out.println(“证书类型:” + certType);X509Certificate x509cert = (X509Certificate) certificate;// 关闭流in.close();return x509cert;}/*** 分析证书文件* @param certficateName 被分析的证书路径名* @throws Exception*/public static void parseX509Certificate(X509Certificate x509cert) throws Exception {// 开始用证书的API提取相关信息:// 读取证书版本号,这个证书的版本号识别用于该证书的X.509标准的版本,它可以用来影响证书所能指定的信息// 迄今为止,已经定义了3个版本int version = x509cert.getVersion();System.out.println(“\n证书版本号为:” + version);// 读取证书序列号BigInteger serialNumber = x509cert.getSerialNumber();System.out.println(“\n证书序列号为:” + (new BASE64Encoder()).encode(serialNumber.toByteArray()));// 读取证书的签名算法名,CA用此算法来签名证书String algName = x509cert.getSigAlgName();System.out.println(“\n证书的签名算法名为:” + algName);// 获得证书的签发者,其名字采用X.500标准,并且给出信息// 这个证书的签发者通常是一个CA,使用该证书意味着信任签写该证书的实体X500Principal issuerPrincipal = x509cert.getIssuerX500Principal();System.out.println(“\n证书的发布者为:” + issuerPrincipal.getName());// 读取出证书的有效期Date notAfter = x509cert.getNotAfter();Date notBefore = x509cert.getNotBefore();System.out.println(“\n证书的有效期为:” + notBefore.toLocaleString() + ” 之后,” + notAfter.toLocaleString() + ” 之前”);// 读取证书的主体,它代表的是公钥的实体,其名字仍然使用X.500标准X500Principal subjectPrincipal = x509cert.getSubjectX500Principal();System.out.println(“证书主题为:” + subjectPrincipal.getName());// 读取证书的公钥PublicKey publicKey = x509cert.getPublicKey();System.out.println(“\n获取证书的公钥信息”);System.out.println(“证书的公钥的算法为:” + publicKey.getAlgorithm());System.out.println(“证书公钥的格式为:” + publicKey.getFormat());// 获得公钥的字节数组byte[] publicKeyBytes = publicKey.getEncoded();System.out.println(“证书公钥为:” + (new BASE64Encoder()).encode(publicKeyBytes));// 读取证书的基本约束System.out.println(“\n证书路径的长度为:” + x509cert.getBasicConstraints());// 证书所含公钥所能完成的功能或者服务boolean[] keyUsages = x509cert.getKeyUsage();// KeyUsage ::= BIT STRING {// digitalSignature (0),// nonRepudiation (1),// keyEncipherment (2),// dataEncipherment (3),// keyAgreement (4),// keyCertSign (5),// cRLSign (6),// encipherOnly (7),// decipherOnly (8) }if (keyUsages[0])System.out.println(“此证书的公钥可以用来数字签名”);if (keyUsages[1])System.out.println(“此证书的公钥具有不可否认性”);if (keyUsages[2])System.out.println(“此证书的公钥可以用于加密”);if (keyUsages[3])System.out.println(“此证书的公钥用于将用户数据加密”);if (keyUsages[4])System.out.println(“此证书的公钥用于密钥协议”);if (keyUsages[5])System.out.println(“此证书的公钥用于验证在证书上的签名”);if (keyUsages[6])System.out.println(“此证书的公钥用于验证有关撤销消息”);if (keyUsages[7])System.out.println(“此证书的公钥只可以用于加密,并且履行密钥协议”);if (keyUsages[8])System.out.println(“此证书的公钥只可以用于解密,并且履行密钥协议”);// 读取证书的签名算法的OID字符串String algOIDString = x509cert.getSigAlgOID();System.out.println(“\n证书的签名算法OID字符串为:” + algOIDString);x509cert.getSigAlgParams();// 读取证书的签名值byte[] certSignature = x509cert.getSignature();System.out.println(“\n证书的签名值为:” + (new BASE64Encoder()).encode(certSignature));x509cert.getSubjectAlternativeNames();// 读取证书的DER编码的二进制证书信息byte[] tbsCertificate = x509cert.getTBSCertificate();System.out.println(“\n证书的DER编码的二进制证书信息为:” + (new BASE64Encoder()).encode(tbsCertificate));}/*** 获取证书的撤销列表* @param certificateName* @return* @throws Exception*/public static CRL getCRLForCertifate(String certificateName) throws Exception {//实例化证书,并且指定证书的类型是X.509CertificateFactory certifateFactory = CertificateFactory.getInstance(“X.509”);//获取证书的输入流FileInputStream in = new FileInputStream(certificateName);//获取证书的撤销列表CRL crl = certifateFactory.generateCRL(in);in.close();return crl;}}

缘是浪漫的相遇,瞬间让你我的心化为永恒!

密码学研究-证书

相关文章:

你感兴趣的文章:

标签云: