写点什么

密码学系列之: 使用 openssl 创建私有 CA

作者:程序那些事
  • 2022 年 5 月 25 日
  • 本文字数:3111 字

    阅读完需:约 10 分钟

密码学系列之:使用openssl创建私有CA

简介

一般情况下我们使用的证书都是由第三方权威机构来颁发的,如果我们有一个新的 https 网站,我们需要申请一个世界范围内都获得认可的证书,这样我们的网站才能被无障碍的访问。


如果在某些情况下,我们的网站或者系统并不是公开的,但是也需要使用 tls 协议的话,那么就需要自己搭建一个 CA 服务器。这样的 CA 服务器就叫做 private CA。


熟悉证书的朋友可能会说了,为什么不使用自签名证书呢?也可以达到安全通信的目的。


这是因为自签名证书的作用比较有限,它没有 CRL 和 OCSP 的能力,并且使用起来也不是很方便。所以我们需要一整套有效的 CA 签发体系,这也是我们需要搭建 private CA 的目的。

搭建 root CA

在搭建 root CA 之前我们需要创建几个合适的目录来保存 CA 的相关信息,比如我们需要一个保存证书的目录 certs,一个保存密钥的地方 keys,一个 CA 数据库 db。


其中 db 需要一个 index 文件,serial 文件和 crlnumber 文件。


我们用下面的命令创建对应的文件和目录:


mkdir certs db keystouch db/indexopenssl rand -hex 16  > db/serialecho 1001 > db/crlnumber
复制代码


目录建好之后,我们还需要一个非常重要的 root ca 配置文件。后续可以根据这个配置文件来创建 CA 相关的信息。


一般情况下 CA 配置文件是不需要的,只有我们需要创建比较复杂 CA 的情况下才需要使用 ca 配置文件。


下面是一个 CA 配置文件的例子:


[default]name                    = root-cadomain_suffix           = flydean.comdefault_ca              = ca_configname_opt                = utf8,esc_ctrl,multiline,lname,align
[ca_config]database = db/indexserial = db/serialcrlnumber = db/crlnumbercertificate = root-ca.crtprivate_key = keys/root-ca.keyRANDFILE = keys/randomnew_certs_dir = certsunique_subject = nocopy_extensions = nonedefault_days = 365default_crl_days = 100default_md = sha256policy = ca_policy
[ca_policy]countryName = matchstateOrProvinceName = optionalorganizationName = matchorganizationalUnitName = optionalcommonName = suppliedemailAddress = optional
[req]default_bits = 4096encrypt_key = yesdefault_md = sha256utf8 = yesstring_mask = utf8onlyprompt = nodistinguished_name = ca_distreq_extensions = ca_req_ext
[ca_dist]countryName = "CN"organizationName = "flydean"commonName = "Root CA"
[ca_req_ext]basicConstraints = critical,CA:truekeyUsage = critical,keyCertSign,cRLSignsubjectKeyIdentifier = hash
[sub_ca_ext]authorityInfoAccess = @issuer_infoauthorityKeyIdentifier = keyid:alwaysbasicConstraints = critical,CA:true,pathlen:0crlDistributionPoints = @crl_infoextendedKeyUsage = clientAuth,serverAuthkeyUsage = critical,keyCertSign,cRLSignsubjectKeyIdentifier = hash
[crl_info]URI.0 = http://crl3.digicert.com/DigiCertTLSRSASHA2562020CA1-4.crl
[issuer_info]caIssuers;URI.0 = http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crtOCSP;URI.0 = http://ocsp.digicert.com
[ocsp_ext]authorityKeyIdentifier = keyid:alwaysbasicConstraints = critical,CA:falseextendedKeyUsage = OCSPSigningnoCheck = yeskeyUsage = critical,digitalSignaturesubjectKeyIdentifier = hash
复制代码

生成 root CA

有了上面的配置文件和目录信息,就可以生成 root CA 了。


首先我们需要创建私钥和 root ca 的 csr 文件如下:


openssl req -new -config root-ca.conf  -out root-ca.csr  -keyout keys/root-ca.key
复制代码


接下来我们创建一个自签名的证书,这里我们需要用到配置文件中的 ca_req_ext 部分:


 openssl ca -selfsign  -config root-ca.conf  -in root-ca.csr   -out root-ca.crt -extensions ca_req_ext
复制代码


运行该命令之后,我们会在 certs 文件夹中创建一个自签名证书文件。


除此之外,还向 db 中的 index 文件中写入了下面的内容:


V  230501041451Z    4445DE5C0285EAEF2E58757D5CB1E949  unknown  /C=CN/O=flydean/CN=Root CA
复制代码


这是一个文本文件,里面保存的是生成的证书索引,证书中的字段是通过 tab 来进行分割的。


第一个字段 V 表示 valid 也就是有效的意思,这个字段还可以有其他几个值,比如 R 表示 revoked,E 表示 expired。


第二个字段是过期时间,格式是 YYMMDDHHMMSSZ。


第三个字段是 Revocation 日期,如果空表示没有 revoked。


第四个字段是序列号,也就是生成的 CA 名字。


第五个字段是文件的位置,unknown 表示未知。


最后一个字段是这个证书的名字,用于和其他的证书做区分。

使用 CRL

有了 root-ca.conf 之后,我们可以使用它来创建 CRL:


openssl ca -gencrl  -config root-ca.conf  -out root-ca.crl
复制代码


现在生成的 root-ca.crl 文件还没有任何证书信息。


如果我们想要撤销某个颁发的 CA,可以使用下面的命令:


openssl ca  -config root-ca.conf  -revoke certs/torevoke.pem -crl_reason unspecified
复制代码


在 revoke 中指定要 revoke 的证书即可。


这里要注意的是我们需要指定 crl_reason,crl_reason 可以是下面几个值:


unspecifiedkeyCompromiseCACompromiseaffiliationChangedsupersededcessationOfOperationcertificateHoldremoveFromCRL
复制代码

使用 OSCP

对于 OSCP 来说,需要一个 OCSP responder 来响应 OCSP 的请求。这个 OCSP responder 和 CA 本身并不是同一个,需要单独创建。


首先,我们创建 OCSP responder 的 key 和证书请求 CSR:


openssl req -new  -newkey rsa:2048  -keyout keys/root-ocsp.key -out root-ocsp.csr
复制代码


当然输入必须的参数之后,key 和 CSR 就可以生成了。


接下来我可以使用 root CA 和 root-ocsp.csr 颁发 OCSP 证书,这里我们需要用到配置文件中的 ocsp_ext 部分。


openssl ca  -config root-ca.conf  -in root-ocsp.csr  -out root-ocsp.crt -extensions ocsp_ext  -days 10
复制代码


上面的命令为 OCSP responder 生成了一个有效期为 10 天的证书。


有了证书,我们可以方便的搭建一个本地的 OCSP responder 如下所示:


openssl ocsp  -port 9000 -index db/index  -rsigner root-ocsp.crt -rkey keys/root-ocsp.key  -CA root-ca.crt  -textEnter pass phrase for keys/root-ocsp.key:Waiting for OCSP client connections...
复制代码


这样我们就启动了一个 OCSP 服务器端。


另开一个窗口,执行下面的命令来请求 OCSP:


 openssl ocsp -issuer root-ca.crt  -CAfile root-ca.crt  -cert root-ocsp.crt   -url http://127.0.0.1:9000
复制代码


可以得到下面的结果:


Response verify OKroot-ocsp.crt: good  This Update: May  1 08:09:31 2022 GMT
复制代码


这就说明 OCSP responder 搭建成功了。


这里启动的是一个本地服务,在正式环境中可以考虑将其迁移到单独的服务器中。

总结

使用上面的命令,我们搭建了一个私有的 CA 服务,和对应的 OCSP,openssl 非常强大,基本上你可以用他来做任何事情。


更多内容请参考 http://www.flydean.com/45-openssl-private-ca/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 20 小时前阅读数: 16
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
密码学系列之:使用openssl创建私有CA_密码学_程序那些事_InfoQ写作社区