创建私有 CA

原创
2023/01/08 22:41
阅读数 85

创建私有 CA

创建根 CA 目录结构

mkdir -p root-ca && cd root-ca && mkdir -p certs db private && chmod 700 private && touch db/index && openssl rand -hex 16 > db/serial && echo 1001 > db/crlnumber

目录说明:

  • certs/ 证书存储目录,颁发的新的证书将保存在此目录
  • db/ 此目录用于保存证书数据库索引及证书及CRL序列化。 OpenSSL 还会创建其他额外的文件。
  • private/ 此目录用于保存一些私钥,如CA私钥及 OCSP 私钥等。实际情况这些CA私钥应该受到严格的保密及限制。

注意 为了避免冲突,创建CA证书时先初始化随机序列号是很重要的。

生成根 CA

  1. 创建 密钥 和 CSR
openssl req -new -config root-ca.conf -out root-ca.csr -keyout private/root-ca.key 

输入密码之后创建OK。

  1. 创建一个自签名证书。 -extensions cat_ext 参数,表示使用 ca_ext 配置块用于 根 CA 的扩展配置 。
openssl ca -selfsign -config root-ca.conf -in root-ca.csr -out root-ca.crt -extentions ca_ext
$openssl ca -selfsign -config root-ca.conf -in root-ca.csr -out root-ca.crt -extensions ca_ext
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            fa:57:6d:84:55:37:3f:05:0e:74:6f:ee:b3:27:60:56
        Issuer:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Root CA
        Validity
            Not Before: Jan  8 12:52:53 2023 GMT
            Not After : Jan  5 12:52:53 2033 GMT
        Subject:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                   // 省略
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:
                82:BE:AA:B1:64:65:57:AB:97:62:ED:25:A6:C3:52:3B:2F:DE:12:6B
Certificate is to be certified until Jan  5 12:52:53 2033 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
➜  root-ca

各 db 目录中文件的内容如下:

$cat db/index
V       330105125253Z           FA576D8455373F050E746FEEB3276056        unknown /C=CN/O=CodeTalks Ltd/CN=CodeTaks Root CA
$cat db/index.attr
unique_subject = no
$cat db/index.old
$cat db/serial
FA576D8455373F050E746FEEB3276057
$cat db/serial.old
fa576d8455373f050e746feeb3276056
$cat db/crlnumber
1001

db/index 文件内容解析如下

V       330105125253Z           FA576D8455373F050E746FEEB3276056        unknown /C=CN/O=CodeTalks Ltd/CN=CodeTaks Root CA

下面对各列进行解释说明:

  • V 表示 Valid, R 表示 Revoked, E 表示 Expired
  • 过期时间,格式为 YYMMDDHHMMSSZ 格式。上面内容就是 2033-01-05 12:52:53Z
  • 撤销日期(如果已经撤销,否则为空)
  • 序列号(16进制)
  • 文件存储路径,或 unknown 如果不知道的话。
  • Distinguished name

根 CA 操作

  1. 生成 CRL 使用 -gencrl ca 子命令
openssl ca -gencrl -config root-ca.conf -out root-ca.crl
$openssl ca -gencrl -config root-ca.conf -out root-ca.crl
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key:
$cat root-ca.crl
-----BEGIN X509 CRL-----
MIICmjCBgwIBATANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJDTjEWMBQGA1UE
CgwNQ29kZVRhbGtzIEx0ZDEZMBcGA1UEAwwQQ29kZVRha3MgUm9vdCBDQRcNMjMw
MTA4MTMxNTI1WhcNMjQwMTA4MTMxNTI1WqAPMA0wCwYDVR0UBAQCAhABMA0GCSqG
SIb3DQEBCwUAA4ICAQBpnlP6S0ULqltW45/3FzQx0dVopZ2rzhzAmAYJ1XWebsv1
3uPIQbvUYdVnQEZ+tBuApmRU0+wzPg8PSgmYV+y3Q7gD5YSzdLJI5bHegLMwtoy2
PWdu6fW5iGCIbfwWJlTYp7yCJDQa1+LSIctP4fuaycw07B/0xexuAw/oSiR/Qc9W
VDbdjAImjX6Q/WQBQgHkj3wz3PFAdMR8/99oLsgmDUGClfZeMccEz7Eninnw4BF5
OFQEr5X0R587wcxyrCfcZGvGZgi/71LjUkdd6ooFYDosiCuhK7w4y9Ux5GmRkCql
xyJTVee9K02esVz9ra1uwr0ZN9XxuiM6S3bOYZByb+PiK12GWKikUR8Yv7Z3Ol7I
juMTDocn9Y9gLhZFaBhBrmxhzRoG1/gBUl9ncmiyjIRrZu4E6APIMH8+sA8xbzHD
itGDAfoHeUf4GPxwGvvtjC0CuU1zmyqI5X6xIPU0pTpX0qOMGtKMgtT2RdLq3jkS
u3D/4Z+sBnmlPQq8u4auxdoD4ZNJJxJLfNDHHOxAJzJV0W7MqTnVV/GXlVTsQ/tH
+Z+WyZS0otMmrpTJri8vnOVOlYZwcsaxg0X1kIinalvGIyBUM8q9M4XimBNxiJSF
BwTsKM/dwsopHCkhfaKXjsaWZ5tFLAo98IA+wYRxpw9d2VMn0Af3J5SR0Qf89g==
-----END X509 CRL-----

为 OCSP 签名创建证书

  1. 创建密钥和 CSR
openssl req -new -newkey rsa:2048 -subj '/C=CN/O=CodeTalks Ltd/CN=OCSP Root Responder' \
 -keyout private/root-ocsp.key -out root-ocsp.csr
a openssl req -new -newkey rsa:2048 -subj '/C=CN/O=CodeTalks Ltd/CN=OCSP Root Responder' \
 -keyout private/root-ocsp.key -out root-ocsp.csr

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
  1. 使用 根 CA 签发证书。 -extensions ocsp_ext 指定使用 ocsp_ext 块的配置
openssl ca -config root-ca.conf -in root-ocsp.csr -out root-ocsp.crt -extensions ocsp_ext -days 30
$openssl ca -config root-ca.conf -in root-ocsp.csr -out root-ocsp.crt -extensions ocsp_ext -days 30
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            fa:57:6d:84:55:37:3f:05:0e:74:6f:ee:b3:27:60:57
        Issuer:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Root CA
        Validity
            Not Before: Jan  8 13:29:59 2023 GMT
            Not After : Feb  7 13:29:59 2023 GMT
        Subject:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = OCSP Root Responder
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus: // 公钥忽略
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Authority Key Identifier:
                82:BE:AA:B1:64:65:57:AB:97:62:ED:25:A6:C3:52:3B:2F:DE:12:6B
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Extended Key Usage:
                OCSP Signing
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Subject Key Identifier:
                00:8C:90:C2:B9:88:4D:E1:B0:7D:56:82:79:5E:FB:12:65:64:D1:23
Certificate is to be certified until Feb  7 13:29:59 2023 GMT (30 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
  1. 启用 OCSP responder
openssl ocsp -port 9080 -index db/index -rsigner root-ocsp.crt -rkey private/root-ocsp.key -CA root-ca.crt -text
$openssl ocsp -port 9080 -index db/index -rsigner root-ocsp.crt -rkey private/root-ocsp.key -CA root-ca.crt -t
ext
ACCEPT 0.0.0.0:9080 PID=2312
Enter pass phrase for private/root-ocsp.key:
ocsp: waiting for OCSP client connections...

客户端连接测试

openssl ocsp -issuer root-ca.crt -CAfile root-ca.crt -cert root-ocsp.crt -url http://127.0.0.1:9080
$openssl ocsp -issuer root-ca.crt -CAfile root-ca.crt -cert root-ocsp.crt -url http://127.0.0.1:9080
Response verify OK
root-ocsp.crt: good
        This Update: Jan  8 13:45:07 2023 GMT

创建下属 CA

  1. 创建目录
mkdir -p sub-ca && cd sub-ca && mkdir -p certs db private && chmod 700 private && touch db/index && openssl rand -hex 16 > db/serial && echo 20001 > db/crlnumber
  1. 创建配置 sub-ca.conf

  2. 创建下属 CA

创建 CSR

openssl req -new -config sub-ca.conf -out sub-ca.csr -keyout private/sub-ca.key
$openssl req -new -config sub-ca.conf -out sub-ca.csr -keyout private/sub-ca.key

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

使用根 CA签发证书

openssl ca -config root-ca.conf -in sub-ca.csr -out sub-ca.crt -extensions sub_ca_ext
$openssl ca -config root-ca.conf -in sub-ca/sub-ca.csr -out sub-ca/sub-ca.crt -extensions sub_ca_ext
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            fa:57:6d:84:55:37:3f:05:0e:74:6f:ee:b3:27:60:58
        Issuer:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Root CA
        Validity
            Not Before: Jan  8 13:57:49 2023 GMT
            Not After : Jan  5 13:57:49 2033 GMT
        Subject:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Sub Web CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus: // 公钥忽略
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            Authority Information Access:
                CA Issuers - URI:http://root-ca.codetalks.com/root-ca.crt
                OCSP - URI:http://ocsp.root-ca.codetalks.com:9080
            X509v3 Authority Key Identifier:
                82:BE:AA:B1:64:65:57:AB:97:62:ED:25:A6:C3:52:3B:2F:DE:12:6B
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 CRL Distribution Points:
                Full Name:
                  URI:http://root-ca.codetalks.com/root-ca.crl
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Name Constraints:
                Permitted:
                  DNS:codetalks.com
                  DNS:codetalks.org
                Excluded:
                  IP:0.0.0.0/0.0.0.0
                  IP:0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
            X509v3 Subject Key Identifier:
                CB:B0:77:B5:84:62:8F:AF:8C:B7:F8:72:2B:8E:20:68:B9:B7:21:81
Certificate is to be certified until Jan  5 13:57:49 2033 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

下属 CA 操作

签收服务端证书

  1. 生成 server.key
openssl genpkey -out server.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048
  1. 生成 server.csr
openssl req -new -key server.key -out server.csr -subj '/C=CN/ST=Hubei/L=Wuhan/O=CodeTalks Ltd/CN=codetalks.com'
openssl ca -config sub-ca.conf -in server.csr -out server.crt -extensions server_ext 
➜  sub-ca $openssl req -new -key server.key -out server.csr -subj '/C=CN/ST=Hubei/L=Wuhan/O=CodeTalks Ltd/CN=*.codetalks.com'
➜  sub-ca $openssl ca -config sub-ca.conf -in server.csr -out server.crt -extensions server_ext
Using configuration from sub-ca.conf
Enter pass phrase for ./private/sub-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            84:ce:32:59:80:4c:e4:3d:92:ed:18:3b:82:c8:61:19
        Issuer:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Sub Web CA
        Validity
            Not Before: Jan  8 14:29:04 2023 GMT
            Not After : Jan  8 14:29:04 2024 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Hubei
            organizationName          = CodeTalks Ltd
            commonName                = *.codetalks.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus: // 公钥
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            Authority Information Access:
                CA Issuers - URI:http://sub-ca.codetalks.com/sub-ca.crt
                OCSP - URI:http://ocsp.sub-ca.codetalks.com:9081
            X509v3 Authority Key Identifier:
                CB:B0:77:B5:84:62:8F:AF:8C:B7:F8:72:2B:8E:20:68:B9:B7:21:81
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 CRL Distribution Points:
                Full Name:
                  URI:http://sub-ca.codetalks.com/sub-ca.crl
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Subject Key Identifier:
                02:9D:39:59:23:C6:EA:ED:80:B1:33:A8:CA:F9:80:A8:FE:37:CF:5C
Certificate is to be certified until Jan  8 14:29:04 2024 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

**创建客户端证书 **

openssl genpkey -out client.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048
openssl req -new -key client.key -out client.csr -subj '/C=CN/ST=Hubei/L=Wuhan/O=CodeTalks Ltd/CN=codetalks clients'
openssl ca -config sub-ca.conf -in client.csr -out client.crt -extensions client_ext

➜  sub-ca $openssl ca -config sub-ca.conf -in client.csr -out client.crt -extensions client_ext
Using configuration from sub-ca.conf
Enter pass phrase for ./private/sub-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            84:ce:32:59:80:4c:e4:3d:92:ed:18:3b:82:c8:61:1a
        Issuer:
            countryName               = CN
            organizationName          = CodeTalks Ltd
            commonName                = CodeTaks Sub Web CA
        Validity
            Not Before: Jan  8 14:36:58 2023 GMT
            Not After : Jan  8 14:36:58 2024 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Hubei
            organizationName          = CodeTalks Ltd
            commonName                = codetalks clients
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus: // 公钥
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            Authority Information Access:
                CA Issuers - URI:http://sub-ca.codetalks.com/sub-ca.crt
                OCSP - URI:http://ocsp.sub-ca.codetalks.com:9081
            X509v3 Authority Key Identifier:
                CB:B0:77:B5:84:62:8F:AF:8C:B7:F8:72:2B:8E:20:68:B9:B7:21:81
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 CRL Distribution Points:
                Full Name:
                  URI:http://sub-ca.codetalks.com/sub-ca.crl
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Subject Key Identifier:
                11:EF:07:D2:F1:15:54:59:D6:3C:A4:F9:64:1E:CB:44:DD:3D:51:E7
Certificate is to be certified until Jan  8 14:36:58 2024 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

附录 1 root-ca.conf

[default]
name = root-ca
domain_suffix = codetalks.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9080
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align

[ca_dn]
countryName = "CN"
organizationName = "CodeTalks Ltd"
commonName = "CodeTaks Root CA"

[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match

[policy_c_o_match]
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_dn
req_extensions = ca_ext

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

[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
# pathlen 为0,表示子SA后面不允许有再有子CA
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
# 限制子CA签发的证书的用途
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
# 为子CA可颁发证书设置限制
nameConstraints = @name_constraints
subjectKeyIdentifier = hash

[crl_info]
URI.0 = $crl_url

[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url

[name_constraints]
# 限制只能为如下DNS颁发证书
permitted;DNS.0=codetalks.com
permitted;DNS.1=codetalks.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash

附录 2 sub-ca.root

[default]
name = sub-ca
domain_suffix = codetalks.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9081
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align

[ca_dn]
countryName = "CN"
organizationName = "CodeTalks Ltd"
commonName = "CodeTaks Sub Web CA"

[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = copy
default_days = 365
default_crl_days = 30
default_md = sha256
policy = policy_c_o_match

[policy_c_o_match]
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_dn
req_extensions = ca_ext

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

[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
# pathlen 为0,表示子SA后面不允许有再有子CA
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
# 限制子CA签发的证书的用途
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
# 为子CA可颁发证书设置限制
nameConstraints = @name_constraints
subjectKeyIdentifier = hash

[crl_info]
URI.0 = $crl_url

[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url

[name_constraints]
# 限制只能为如下DNS颁发证书
permitted;DNS.0=codetalks.com
permitted;DNS.1=codetalks.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash

[server_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier = hash

[client_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部