• keytool生成证书以及生成证书链


    1. 基础

    1.1. SSL

    证书通常使用在SSL(Secure Sockets Layer安全套接字协议)传输协议中,用于实现端侧与服务侧的密钥交换。现在应该叫它"TLS",但是由于习惯的原因,还是常叫它"SSL"。SSL使用场景最多的是在网站上,用它实现安全的HTTP传输。

    HTTP协议传输是不加密内容的,这样,内容在传播的时候,就可能被人监听。在安全性要求较高的场景中,必须加密传输,比如,登录时传输密码的场景。

    HTTPS就是带加密的HTTP协议,而HTTPS的加密传输是基于SSL实现的,使得,即使在网络传输中的某个节点别人监听,也不会泄露数据。SSL是在HTTP的下层实现加解密,加解密对用户和开发者来说,都是透明的。也就是说,在加密前,你的服务器是怎样实现的,加密后,不用做任何改变。

    还有一个名词就是OpenSSL。简单地说,SSL是一种规范,而OpenSSL是SSL的一个实现,提供了一堆强大的工具,强大到90%我们都用不到。理论上来说,目前的技术水平很难破解SSL,但是SSL的实现却可能有漏洞,如著名的”心脏出血“。

    1.2. 什么是证书

    SSL中用到证书,那么证书是什么?

    证书可以理解为一个包含了签发方信息、拥有者信息、公钥、由签发方私钥产生的签名等信息的文档,当然还包括其他一些信息。校验用户证书是否可信,实际上就是检验该证书是否由合法的机构签发的。校验时,通过该证书中的结构信息找到对应机构的证书,利用机构证书中的公钥去校验用户证书中的签名是否正确。

    从上述校验方法可以看出,证书是否可信,是由其签发方证书来校验的,而机构的证书是否可信,是由上一层机构的证书来校验的,如此就形成一条证书链,最顶层机构的证书的就是常说的根证书。

    在网站的场景中,网站产生密钥库,记录网站的公钥、私钥及其他一些信息;然后从机构申请证书。生成的证书中包括了公钥等信息,同时包括了证书链,用来发布给网站的用户。用户访问网站时,先下载网站证书,校验证书链,然后使用其中的公钥与网站交换密钥。

     

    1.3. 证书的种类


    一种是自签证书,另一种是由机构签发的证书。

    自签证书,也就是颁发者是自己,使用自己的私钥来对证书的信息进行签名。根证书就是自签证书。客户端一般预置了知名机构的根证书,并且信任由这些根证书签发的证书。

    颁发证书,就是通过这些机构签发证书,可能是根级机构,也可能是二级机构,使用机构的私钥来对证书的信息进行签名。

    1.4. 证书的生成

    可以通过openssl或者jdk提供的keytool来生成证书、以及证书对应的密钥库。本文使用keytool举例。理解了证书生成的过程后,可以很容易对应到openssl的生成方法。

    1.5. 基本概念

    随便搜一下TLS证书,会出现一大堆关键字:X.509、p12、pfx、pkcs、pem、csr、cer、crt、jks、crl等,如此繁杂,一下就让人想从入门到放弃。所以,先把这些关键词理一理。

    1.5.1. X.509

    X.509就是一个广泛应用的数字证书标准,简单来说就是定义了数字证书里面包含哪些字段、如何存储,可以参照RFC5280。协议中定义的参数都是采用DER编码(Distinguished Encoding Rules,X.690)。DER编码可以理解为一种TLV(Tag Length Value)格式编码。以一个实际的证书内容为例:

    Certificate:

    Data:

    Version: 3 (0x2) //表示为X509 v3版本证书

    Serial Number: 1 (0x1) //序列号,签发时需保证同一签发方的每个证书都唯一的Serial Number

    Signature Algorithm: sha256WithRSAEncryption //签名算法,先计算SHA256摘要,再使用签发方私钥进行RSA加密

    Issuer: C=CN,ST=JS, L=NJ, O=Dreamer, OU=Dreamer, CN=Dreamer //签发方DN(Distingushed Name),见后续说明

    Validity //证书有效期

    Not Before: Jul 29 14:02:13 2018 GMT

    Not After : Jul 26 14:02:13 2028 GMT

    Subject: C=CN, ST=JS, O=Dreamer, OU=JM, CN=*.dreamer.com //证书拥有方DN(Distingushed Name)

    Subject Public Key Info: //证书公钥信息

    Public Key Algorithm: rsaEncryption

    Public-Key: (1024 bit)

    Modulus:

    00:c5:b8:68:a2:9c:bd:11:0c:83:34:a2:97:a5:8e:

    72:75:2a:bc:f4:75:fc:d0:a3:47:7d:e4:6b:4f:ed:

    dd:79:7c:0f:ce:6e:e7:d2:7d:10:cd:e8:07:56:34:

    58:e3:2b:2e:c9:e3:7f:ae:27:2d:f7:a3:17:6f:dd:

    65:d7:f8:4f:d0:be:9c:3b:9b:ea:ed:86:d2:19:67:

    81:60:53:64:c9:d1:be:17:7d:5d:7f:cc:58:1d:b6:

    e1:51:0d:ba:32:ac:4d:73:a4:fc:8f:6a:79:f9:44:

    25:03:b6:1c:3e:0f:e9:b8:36:b1:07:07:59:54:40:

    d7:2c:52:ab:68:fe:ed:e2:6f

    Exponent: 65537 (0x10001)

    X509v3 extensions: //v3版本扩展信息

    X509v3 Basic Constraints:

    CA:FALSE //表示证书拥有方是否是CA机构,可签发证书,如为True,则还可添加一个pathLengthConstraint来显示签发链的长度

    Netscape Comment:

    OpenSSL Generated Certificate

    X509v3 Subject Key Identifier: //证书拥有方密钥ID,CA: TRUE时需要加入此扩展

    67:30:EE:FB:39:A4:92:56:9C:1A:E8:94:10:A4:3B:EA:EC:2E:04:9E

    X509v3 Authority Key Identifier: //证书签发方对应的密钥ID,用于查找签发方公钥(特别是存在多个密钥时)

    DirName:/C=CN/ST=JS/L=NJ/O=Dreamer/OU=Dreamer/CN=Dreamer

    serial:A0:09:E3:A9:D2:C1:86:7C

    X509v3 Subject Alternative Name: //证书拥有方的别名,用于多域名证书的签发

    DNS:*.example.com, DNS:*.jm.com

    Signature Algorithm: sha256WithRSAEncryption //签发机构对证书的签名信息

    91:db:9b:0c:9b:6e:68:24:d3:2f:3a:67:b5:c0:6c:f0:c8:4c:

    f8:87:86:93:eb:fc:dc:ef:dc:7b:2e:2c:0e:7b:52:23:4d:de:

    d9:69:a8:ee:ae:aa:14:04:ca:1a:03:87:fe:11:60:fe:16:8f:

    87:9d:9e:d0:3a:be:33:03:f6:25:8a:10:37:f8:90:9d:67:5c:

    36:a6:1e:3c:59:d9:8f:eb:22:0e:f7:3c:7d:47:10:9b:0b:03:

    f0:8c:70:b0:3c:40:c6:5d:cc:6b:ba:40:ce:89:04:c7:3c:be:

    af:bd:1d:94:6b:83:39:29:74:de:12:fc:63:0d:0f:39:31:3b:

    48:fd

    除了注释中的说明外,还需要补充以下几点:

    • Subject和Issuer均为DN格式,常见格式为:C=国家,ST=省市, L=区县市, O=组织机构, OU=组织单位, CN=通用名称;
    • DN是证书链查找的关键,验证时会根据Issuer的DN去匹配机构的证书,具体的匹配方法是比较DN的数量以及各DN参数值;
    • DN中的CN通用名称一般为域名,如需支持子域名,例如server.com、bcd.server.com,可使用泛域名形式*.server.com;
    • Subject Alternative Name扩展字段可用于多域名证书。


    1.5.2. 证书编码格式(DER&PEM)


    X.509中说明证书各个字段编码均适用DER格式的编码,证书是一个二进制格式文件。

    那PEM(Privacy Enhanced Mail)又是什么格式呢?按照网上普遍说法,X.509有DER和PEM两种编码格式,其实这种说法个人认为有些不妥,实际上这两种编码格式并不在一个层面上。前面说过DER是一种TLV格式的二进制编码协议,那PEM是否也类似呢?其实PEM并没有去理解X.509的内部参数,而是在X.509进行DER编码之后,对二进制数据做了一次BASE64编码,然后加上文件头尾,如下所示:

    -----BEGIN CERTIFICATE-----
    MIICMTCCAZoCCQCgCeOp0sGGfDANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJD
    TjELMAkGA1UECAwCSlMxCzAJBgNVBAcMAk5KMRAwDgYDVQQKDAdEcmVhbWVyMRAw
    DgYDVQQLDAdEcmVhbWVyMRAwDgYDVQQDDAdEcmVhbWVyMB4XDTE4MDcyODE1NTEx
    NFoXDTI4MDcyNTE1NTExNFowXTELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkpTMQsw
    CQYDVQQHDAJOSjEQMA4GA1UECgwHRHJlYW1lcjEQMA4GA1UECwwHRHJlYW1lcjEQ
    MA4GA1UEAwwHRHJlYW1lcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwjDr
    aM8SubYIN/dqmJLCHYWBet7yQ80H3VPcbeYPja2Fq1VPb0vKMXzfd8BdaJ3roown
    ZCJlfxCFPqN/z8/a0BS+ukmknOcYeYoN+vpVg9Oq3fH0iy+TRg+ydOVwmyAXJk0D
    GS7WFjHv6DYRlH/xgKXuHGXwytNpQHZdDzq6bV0CAwEAATANBgkqhkiG9w0BAQsF
    AAOBgQCaoAdYiWpGKcvc89ZPwL/Zd0KgSLnAln/38a69N5LqtDgWD9a6PDjHHmTF
    /cN/p8hJ3LdEXfPGtFj06+KaG6OVOAo5RSqOHc5DcMs1nAImqIAuLt2rOCmsY+li
    T9tweI2raih6OMTKAeIW5m46T28oPlNgeEMy2Uj2CevS6tCaLQ==
    -----END CERTIFICATE-----

    区分DER、PEM的方法很简单,打开有乱码的是DER格式,打开类似上面格式的就是PEM格式。通常而言,存放DER的文件扩展名为“.cer”,是二进制数据,而存放PEM的文件扩展名为“.crt”,是ASCII码的文本文件。

    DER/PEM文件可以使用以下命令查看:

    openssl x509 -in certificate.der -inform der -text -noout
    openssl x509 -in certificate.pem -text -noout


    1.5.3. 证书相关的扩展名

    扩展名是比较容易误导人的地方,除了.der或.pem后缀外,还有以下常见后缀:

    crt 应该是certificate的缩写,常见于*nix系统,大多是PEM编码,也可能是DER编码
    cer Certificate Signing Request,常见于Windows系统,大多是DER编码,也可能是PEM编码
    key 用户存放密钥信息,可能是DER编码,也可能是PEM编码。可参照PKCS#1(RFC8017)查看其具体字段和定义;但密钥明文存储方式有危险,一般使用PKCS#8格式(RFC5958)加密存储,即设置一个提取密钥
    csr 证书签发请求,其实与证书内容相似,但不包含签发方信息,签发方根据csr并添加自身的签发信息,从而生成证书文件,详情可参照(PKCS#10 RFC2314)
    pfx/p12

    将证书和私钥一并打包成一个文件,并且设置“提取密码”;

    【注意】PKCS12不支持设置密钥库条目密码,默认与密钥库密码一致

    jks

    keystore

    truststore

    jks(Java Key Storage)常见于JAVA相关应用,实际上和PKCS12类似,将证书和私钥一并打包并设置“提取密码”。至于keystore和truststore只是概念上的区别,keystore一般表示用户或服务器证书,而truststore一般表示CA证书

    想要深入研究,可以看一下PKCS协议族,上述的key、csr、pfx/p12等都是该协议族中定义的扩展。

    1.6. 查看证书

    1.6.1. Windows

    在开始菜单的运行中,输入certlm.msc管理本地计算机的证书,或certmgr.msc管理当前用户的证书。

    1.6.2. Android


    以荣耀为例,其他类型手机操作都类似。

    在设置中搜索“证书”,可以找到“安装证书”与“受信任的凭据”。在受信任的凭据中可以看到“系统”与“当前用户”两类证书,两个列表中可以打开或关闭相应的证书。

    在安装证书中可以安装自己的证书。这个操作难度较大,不推荐让用户自己操作。

    2. 生成根证书

    2.1. 生成根证书密钥库

    根证书是一张自签名的证书,使用者和颁发者都是自己。使用下面的命令生成根证书的密钥库(如果不指定keystore文件路径,则默认存在用户目录下的.keystore中),输入密钥库的密码,填写根证书的信息。

    keytool -genkeypair -validity 36500 -keyalg RSA -keypass 123456 -storepass 123456 -alias rootca -keystore root.keystore

    此命令使用RSA算法,,并保存到root.keystore中。

    使用以下命令查看密钥库的信息,会发现发布者与所有者都是testroot:

    keytool -list -keystore root.keystore -keypass 123456 -storepass 123456 -v

    2.2. 从根证书密钥库导出根证书

    导出证书:

    keytool -exportcert -validity 36500 -alias rootca -file root.cer -keystore root.keystore -keypass 123456 -storepass 123456

    查看证书:

     

    3. 生成二级证书

    3.1. 生成二级证书密钥库

    二级证书需要由根证书签发。

    首先使用keytool生成二级证书的密钥库,但是此时还是自签的,我们需要从中生成一个二级证书请求(其中包含了二级证书的公钥);
    然后将证书请求发送到rootca签发二级证书;
    最后,我们将rootca签发的二级证书导入到证书密钥库中,完成二级证书的生成。
    下面命令是生成二级证书密钥库,密钥库的名称为subca,此时仍是自签的,证书颁发者和使用者都是自已:

    keytool -genkeypair -validity 36500 -keyalg RSA -keypass 123456 -storepass 123456 -alias subca -keystore sub.keysto

    3.2. 从二级证书密钥库中生成证书请求

    从二级CA密钥库中导出证书请求,下面是导出证书请求的命令,subca是上面生成的二级CA密钥库的名字,最终导出证书请求文件为subca.csr:

    keytool -certreq -alias subca -file sub.csr -keystore sub.keystore -keypass 123456 -storepass 123456

    3.3. 使用根证书签发证书

    通过keytool工具的签发证书功能,使用rootca对二级证书请求(subca.csr)签发一张二级证书。命令如下,alias指定证书的颁发者,infile指定证书请求文件,outfile是二级证书的文件名:

    keytool -gencert -validity 36500 -alias rootca -infile sub.csr -outfile sub.cer -keystore root.keystore -keypass 123456 -storepass 123456


    3.4. 导入二级证书到密钥库中


    因为本地生成的密钥库仍然是自签名的,此时需要将根证书签发的二级证书导入密钥库中,导入前需要先见自签名的根证书导入密钥库,这点非常重要,否则会报”无法从回复中建立链“,命令如下:

    keytool -importcert -alias rootca -file root.cer -keystore sub.keystore -storepass 123456 -keypass 123456


    然后,才能导入sub.cer到密钥库,alias subca就是之前用来生成密钥库或证书请求时用到的秘钥对别名:

    keytool -importcert -alias subca -file sub.cer -keystore sub.keystore -storepass 123456 -keypass 123456


    此时查看一下密钥库中的subca的秘钥对的证书的颁发者。

    keytool -list -alias subca -v -keystore sub.keystore -storepass 123456



  • 相关阅读:
    Lucene全文检索
    数据库设计样例
    tortoisegit 保存用户名密码
    ServletContextListener 解析用法
    !! 浅谈Java学习方法和后期面试技巧
    佳能2780打印机老出5100错误
    蓝屏
    股市口诀
    如何准确进行T+0操作
    通达信:显示K线图日期
  • 原文地址:https://www.cnblogs.com/cenvent/p/16850230.html
Copyright © 2020-2023  润新知