2

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

 1 year ago
source link: http://www.flydean.com/45-openssl-private-ca/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一般情况下我们使用的证书都是由第三方权威机构来颁发的,如果我们有一个新的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 keys
touch db/index
openssl rand -hex 16  > db/serial
echo 1001 > db/crlnumber

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

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

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

[default]
name                    = root-ca
domain_suffix           = flydean.com
default_ca              = ca_config
name_opt                = utf8,esc_ctrl,multiline,lname,align

[ca_config]
database                = db/index
serial                  = db/serial
crlnumber               = db/crlnumber
certificate             = root-ca.crt
private_key             = keys/root-ca.key
RANDFILE                = keys/random
new_certs_dir           = certs
unique_subject          = no
copy_extensions         = none
default_days            = 365
default_crl_days        = 100
default_md              = sha256
policy                  = ca_policy

[ca_policy]
countryName             = match
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[req]
default_bits            = 4096
encrypt_key             = yes
default_md              = sha256
utf8                    = yes
string_mask             = utf8only
prompt                  = no
distinguished_name      = ca_dist
req_extensions          = ca_req_ext

[ca_dist]
countryName             = "CN"
organizationName        = "flydean"
commonName              = "Root CA"

[ca_req_ext]
basicConstraints        = critical,CA:true
keyUsage                = critical,keyCertSign,cRLSign
subjectKeyIdentifier    = hash

[sub_ca_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:true,pathlen:0
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth,serverAuth
keyUsage                = critical,keyCertSign,cRLSign
subjectKeyIdentifier    = hash

[crl_info]
URI.0                   = http://crl3.digicert.com/DigiCertTLSRSASHA2562020CA1-4.crl

[issuer_info]
caIssuers;URI.0         = http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crt
OCSP;URI.0              = http://ocsp.digicert.com

[ocsp_ext]
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
extendedKeyUsage        = OCSPSigning
noCheck                 = yes
keyUsage                = critical,digitalSignature
subjectKeyIdentifier    = 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可以是下面几个值:

unspecified
keyCompromise
CACompromise
affiliationChanged
superseded
cessationOfOperation
certificateHold
removeFromCRL

使用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  -text
Enter 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 OK
root-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/

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK