zoukankan      html  css  js  c++  java
  • 使用 OpenSSL 创建私有 CA:1 根证书

    OpenSSL 创建私有 CA 三部曲:
    使用 OpenSSL 创建私有 CA:1 根证书
    使用 OpenSSL 创建私有 CA:2 中间证书
    使用 OpenSSL 创建私有 CA:3 用户证书

    OpenSSL 是一个免费开源的库,它提供了一些处理数字证书的命令行工具。其中一些工具可以用作证书颁发机构(Certificate Authority 即 CA)。
    证书颁发机构(CA)是签署数字证书的实体。许多网站需要让他们的客户知道连接是安全的,所以需要从一个被广泛信任的CA(例如VeriSign, DigiCert)来为他们的域名签署证书,也就是我们常说的 HTTPS 证书。
    本系列文章的目的不是让你创建像 VeriSign 那样的 CA 机构。在很多情况下,我们需要在公司局域网内的网站中启用 HTTPS,比如测试环境,或者是公司内网中的管理系统(现在主流的浏览器都把 HTTP 站点标记为不安全)。此时通过 OpenSSL 创建私有 CA 并颁发证书就是很好的选择了。
    本系列分为三篇文章,即本文《使用 OpenSSL 创建私有 CA:1 根证书》后续的《使用 OpenSSL 创建私有 CA:2 中间证书》和《使用 OpenSSL 创建私有 CA:3 用户证书》。
    说明:本系列文章的演示环境为 Ubuntu 18.04,OpenSSL 的版本为 1.1.0g。

    基本目录结构

    创建 myca 目录保存 CA 相关的所有内容,然后创建 myca/rootca 目录用来保存根证书相关的内容:

    至于上图中的 myca/powerca 和 myca/usercert 则存放后面要介绍的中间证书和用户证书的内容。

    准备根证书的配置文件

    OpenSSL 程序提供了一个默认的配置文件:/etc/ssl/openssl.cnf,但是由于我们自定义的内容比较多,所以干脆创建一个套单独的配置文件。创建文件 rootca/rootca.cnf,编辑其内容如下:

    # OpenSSL root CA configuration file.
    # v1
    [ ca ]
    # `man ca`
    default_ca = CA_default
    [ CA_default ]
    # Directory and file locations.
    dir = /home/nick/projects/myca/rootca
    certs = $dir/certs
    crl_dir = $dir/crl
    new_certs_dir = $dir/newcerts
    database = $dir/db/index
    serial = $dir/db/serial
    RANDFILE = $dir/private/random
    # The root key and root certificate.
    private_key = $dir/private/rootca.key.pem
    certificate = $dir/certs/rootca.cert.pem
    # For certificate revocation lists.
    crlnumber = $dir/db/crlnumber
    crl = $dir/crl/rootca.crl.pem
    crl_extensions = crl_ext
    default_crl_days = 30
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md = sha256
    name_opt = ca_default
    cert_opt = ca_default
    default_days = 3750
    preserve = no
    policy = policy_strict
    [ policy_strict ]
    # The root CA should only sign intermediate certificates that match.
    # See the POLICY FORMAT section of `man ca`.
    countryName = match
    stateOrProvinceName = match
    organizationName = match
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional
    [ req ]
    # Options for the `req` tool (`man req`).
    # Optionally, specify some defaults.
    prompt = no
    input_password = 123456
    
    default_bits = 2048
    distinguished_name = req_distinguished_name
    string_mask = utf8only
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md = sha256
    # Extension to add when the -x509 option is used.
    # make sure use x509_extensions, do not use req_extensions.
    x509_extensions = v3_ca
    # use the req_extensions not work.
    #req_extensions = v3_ca
    [ req_distinguished_name ]
    # See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
    countryName = CN
    stateOrProvinceName = ShaanXi
    localityName = Xian
    organizationName = NickLi Ltd
    organizationalUnitName = NickLi Ltd CA
    commonName = NickLi Root CA
    emailAddress = ljfpower@163.com
    [ v3_ca ]
    # Extensions for a typical CA (`man x509v3_config`).
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    [ v3_intermediate_ca ]
    # Extensions for a typical intermediate CA (`man x509v3_config`).
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true, pathlen:0
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    [ crl_ext ]
    # Extension for CRLs (`man x509v3_config`).
    authorityKeyIdentifier=keyid:always
    [ ocsp ]
    # Extension for OCSP signing certificates (`man ocsp`).
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, digitalSignature
    extendedKeyUsage = critical, OCSPSigning

    这是一个非常重要的配置文件,指定了很多配置的目录,其中最重要的一个已经被抽取成了变量 dir。我们要做的就是指定 dir 的路径,并且根据下面的步骤来创建其余的目录和文件。
    为了把创建证书的过程也自动化掉,笔者在 req 段添加了下面的配置:

    [ req ]
    prompt = no
    input_password = 123456

    其中的 123456 就是后面创建的秘钥的密码,这样在创建 Certificate Signing Requests(csr) 时就不需要以交互的方式输入密码了。
    下面的内容是默认的 CA 信息:

    [ req_distinguished_name ]
    countryName = CN
    stateOrProvinceName = ShaanXi
    localityName = Xian
    organizationName = NickLi Ltd
    organizationalUnitName = NickLi Ltd CA
    commonName = NickLi Root CA
    emailAddress = ljfpower@163.com

    准备目录和文件

    在 rootca 目录下创建下面的目录和文件:

    rootca/certs/           # 存放新建的证书
    rootca/db/              # spenssl 用来存放信息的目录
    rootca/private/         # 存放私钥
    rootca/crl/                                 
    rootca/newcerts/
    
    rootca/db/index
    rootca/db/serial
    rootca/db/crlnumber

    其中的 rootca/private 目录需要 700 的权限,主要是为了既保证私钥的安全有能够创建私钥文件。rootca/db/serial 和 rootca/db/crlnumber 则需要被初始化为特定的值。简单起见我们可以使用下面的脚本来创建这些目录和文件:

    #!/bin/bash
    
    # create dir certs db private crl newcerts under rootca dir.
    if [ ! -d rootca/certs ]; then
        mkdir -p rootca/certs
    fi
    
    if [ ! -d rootca/db ]; then
        mkdir -p rootca/db
        touch rootca/db/index
        openssl rand -hex 16 > rootca/db/serial
        echo 1001 > rootca/db/crlnumber
    fi
    
    if [ ! -d rootca/private ]; then
        mkdir -p rootca/private
        chmod 700 rootca/private
    fi
    
    if [ ! -d rootca/crl ]; then
        mkdir -p rootca/crl
    fi
    
    if [ ! -d rootca/newcerts ]; then
        mkdir -p rootca/newcerts
    fi

    把上面的代码保存到 myca/roothelpler.sh 文件中,然后 cd 到 myca 目录下执行:

    $ ./roothelpler.sh

    此时当前目录为 myca,rootca 下的子目录和文件都已经创建成功。

    创建 root 秘钥

    进入 rootca 目录:

    $ cd rootca

    执行下面的命令创建私钥:

    $ openssl genrsa -aes256 -out private/rootca.key.pem 4096

    这里笔者设置的密码为:123456,记住这个密码,后面还会用到。然后为了确保安全,把秘钥的访问权限设置为 400:

    $ chmod 400 private/rootca.key.pem

    此时当前目录为 myca/rootca。

    创建 Certificate Signing Requests(csr)

    执行下面的命令创建 csr:

    $ openssl req -new 
        -config rootca.cnf 
        -sha256 
        -key private/rootca.key.pem 
        -out csr/rootca.csr.pem

    下面的命令可以检查生成的 csr:

    $ openssl req -text -noout -in csr/rootca.csr.pem

    注意,csr 中包含了 CA 的基本信息,和公钥信息。

    创建 CA 的根证书

    有了前一步中生成的 csr,我们就可以通过下面的命令生成 CA 的根证书了:

    $ openssl ca -selfsign 
        -config rootca.cnf 
        -in csr/rootca.csr.pem 
        -extensions v3_ca 
        -days 7300 
        -out certs/rootca.cert.pem

    在交互式的提示中输入私钥的密码 123456,并同意其它的确认提示,就完成了根证书的生成操作。注意,上面命令中的 -selfsing 选项,它说明所有的根证书都是自签名的。同样,我们也可以通过命令来查看证书的详细信息:

    $ openssl x509 -noout -text -in certs/rootca.cert.pem

    其中的 Signature Algorithm 为签名算法;Issurer 是签发方,即签署证书的实体;Validity 指明证书的有效期为 2018-11-26 号至 2038-11-21 号;然后是公钥信息;Subject 指明证书自身的信息,这里 Issurer 和 Subject 的信息是一样的;下面还有 X509 协议相关的信息,这部分信息由配置文件 rootca.cnf 中的 [ v3_ca ] 段控制:

    红框中的信息表明这个证书被用作 CA。

    总结

    至此我们已经为私有的 CA 创建了根证书,在接下来的《使用 OpenSSL 创建私有 CA:中间证书》一文中我们将详细的介绍如何创建 CA 的中间证书。

    参考:
    OpenSSL Certificate Authority
    《openssl-cookbook》

  • 相关阅读:
    Nio笔记(一)
    设计模式之职责链模式
    Hibernate注解(三)
    Hibernate注解(二)
    Hibernate注解(一)
    设计模式之适配器模式
    设计模式之桥接模式
    设计模式之外观模式
    设计模式之观享元模式
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/sparkdev/p/10369313.html
Copyright © 2011-2022 走看看