OpenSSL生成证书链多级证书

初始化

rm -rf /etc/pki/CA/*.old
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
echo 02 > /etc/pki/CA/serial
rm -rf keys
mkdir keys

生成根CA并自签(Common Name填RootCA)

[root@localhost CA]# openssl genrsa  -out keys/RootCA.key 2048

Generating RSA private key, 2048 bit long modulus

................+++

......+++

e is 65537 (0x10001)

[root@localhost CA]# openssl req -new -x509 -days 3650 -key keys/RootCA.key -out keys/RootCA.crt

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [XX]:CN

State or Province Name (full name) []:BJ

Locality Name (eg, city) [Default City]:BJ

Organization Name (eg, company) [Default Company Ltd]:BJ

Organizational Unit Name (eg, section) []:BJ

Common Name (eg, your name or your server's hostname) []:benet.com

Email Address []:

  

生成二级CA(Common Name填secondCA)

[root@localhost CA]#  openssl rsa -in keys/secondCA.key -out keys/secondCA.key
writing RSA key
[root@localhost CA]# openssl req -new -days 3650 -key keys/secondCA.key -out keys/secondCA.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:BJ
Organizational Unit Name (eg, section) []:BJ
Common Name (eg, your name or your server's hostname) []:benet.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost CA]# openssl ca -extensions v3_ca -in keys/secondCA.csr -config /etc/pki/tls/openssl.cnf -days 3650 -out keys/secondCA.crt -cert keys/RootCA.crt -keyfile keys/RootCA.key
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Aug 21 09:22:09 2020 GMT
            Not After : Aug 19 09:22:09 2030 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BJ
            organizationName          = BJ
            organizationalUnitName    = BJ
            commonName                = benet.com
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                C0:03:65:8D:DC:95:F2:E1:52:FE:04:65:EF:12:4E:69:8A:C5:F9:24
            X509v3 Authority Key Identifier: 
                keyid:EC:1F:44:CC:E3:28:64:F7:3F:5A:D5:2A:53:AF:A0:94:73:02:47:2B

            X509v3 Basic Constraints: 
                CA:TRUE
Certificate is to be certified until Aug 19 09:22:09 2030 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(Common Name填thirdCA)

[root@localhost CA]# openssl rsa -in keys/thirdCA.key -out keys/thirdCA.key
writing RSA key
[root@localhost CA]# openssl req -new -days 3650 -key keys/thirdCA.key -out keys/thirdCA.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:BJ
Organizational Unit Name (eg, section) []:BJ
Common Name (eg, your name or your server's hostname) []:benet.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost CA]# openssl ca -extensions v3_ca -in keys/thirdCA.csr -config /etc/pki/tls/openssl.cnf -days 3650 -out keys/thirdCA.crt -cert keys/secondCA.crt -keyfile keys/secondCA.key
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Aug 21 09:23:58 2020 GMT
            Not After : Aug 19 09:23:58 2030 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BJ
            organizationName          = BJ
            organizationalUnitName    = BJ
            commonName                = benet.com
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                8B:6F:B5:3C:8C:0A:26:5B:F6:13:23:A9:21:8F:2E:05:6C:EC:C3:78
            X509v3 Authority Key Identifier: 
                keyid:C0:03:65:8D:DC:95:F2:E1:52:FE:04:65:EF:12:4E:69:8A:C5:F9:24

            X509v3 Basic Constraints: 
                CA:TRUE
Certificate is to be certified until Aug 19 09:43:00 2030 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签发服务器证书

[root@localhost CA]# openssl genrsa  -out keys/server.key 2048
Generating RSA private key, 2048 bit long modulus
.......................................................+++
..................................................................................+++
e is 65537 (0x10001)
[root@localhost CA]# openssl rsa -in keys/server.key -out keys/server.key
writing RSA key
[root@localhost CA]#  openssl req -new -days 3650 -key keys/server.key -out keys/server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:BJ
Organizational Unit Name (eg, section) []:BJ
Common Name (eg, your name or your server's hostname) []:golang.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost CA]#  openssl ca -in keys/server.csr -config /etc/pki/tls/openssl.cnf -days 3650 -out keys/server.crt -cert keys/thirdCA.crt -keyfile keys/thirdCA.key
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4 (0x4)
        Validity
            Not Before: Aug 21 09:43:00 2020 GMT
            Not After : Aug 19 09:43:00 2030 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BJ
            organizationName          = BJ
            organizationalUnitName    = BJ
            commonName                = golang.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                F9:77:DE:5C:16:CF:D1:9B:7F:96:30:D8:CF:2C:8C:0F:E0:2E:F8:34
            X509v3 Authority Key Identifier: 
                keyid:C1:54:59:0B:84:D7:F5:23:36:FD:AE:AF:E7:3F:30:D6:A7:2A:8B:39

Certificate is to be certified until Aug 19 09:43:00 2030 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

  

最后将RootCA导入受信任的根证书颁发机构,其他两个证书导入中级CA机构,服务器证书根据需要导入

结果如下:

报错情况记录

The mandatory stateOrProvinceName field was missing

原因openssl.cnf中CA policy有三个match,必须要填一样的,或者改成optional

复制代码
# For the CA policy
[ policy_match ]
countryName        = match
stateOrProvinceName    = match
organizationName    = match
organizationalUnitName    = optional
commonName        = supplied
emailAddress        = optional
复制代码

解决方法:

分别填CN、LiaoNing、ORG

 

清空文件再次生成证书报错

ERROR:Serial number 01 has already been issued,
      check the database/serial_file for corruption

官方承认这是个bug

解决方法:/etc/pki/CA/serial这个文件实际上清空还是会记录生成证书的次数,所以把它改成比较大的数

报错

failed to update database
TXT_DB error number 2

这个也是bug,三个方法

产生的原因是:
This thing happens when certificates share common data. You cannot have two
certificates that look otherwise the same.
方法一:
修改demoCA下 index.txt.attr
将unique_subject = yes改为unique_subject = no
方法二:
删除demoCA下的index.txt,并再touch下rm index.txt touch index.txt
方法三:
将 common name设置成不同的

openssl官方在2014年6月修复了这个已经存在十年的问题
http://rt.openssl.org/Ticket/Display.html?id=502&user=guest&pass=guest

补充:

CentOS7.X完整的openssl.cnf配置文件

[root@localhost ~]# cat /etc/pki/tls/openssl.cnf
HOME            = .
RANDFILE        = $ENV::HOME/.rnd
oid_section        = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ ca ]
default_ca    = CA_default        # The default ca section
[ CA_default ]
dir        = /etc/pki/CA        # Where everything is kept
certs        = $dir/certs        # Where the issued certs are kept
crl_dir        = $dir/crl        # Where the issued crl are kept
database    = $dir/index.txt    # database index file.
                    # several ctificates with same subject.
new_certs_dir    = $dir/newcerts        # default place for new certs.
certificate    = $dir/cacert.pem     # The CA certificate
serial        = $dir/serial         # The current serial number
crlnumber    = $dir/crlnumber    # the current crl number
                    # must be commented out to leave a V1 CRL
crl        = $dir/crl.pem         # The current CRL
private_key    = $dir/private/cakey.pem# The private key
RANDFILE    = $dir/private/.rand    # private random number file
x509_extensions    = usr_cert        # The extentions to add to the cert
name_opt     = ca_default        # Subject Name options
cert_opt     = ca_default        # Certificate field options
default_days    = 365            # how long to certify for
default_crl_days= 30            # how long before next CRL
default_md    = sha256        # use SHA-256 by default
preserve    = no            # keep passed DN ordering
policy        = policy_match
[ policy_match ]
countryName        = match
stateOrProvinceName    = match
organizationName    = match
organizationalUnitName    = optional
commonName        = supplied
emailAddress        = optional
[ policy_anything ]
countryName        = optional
stateOrProvinceName    = optional
localityName        = optional
organizationName    = optional
organizationalUnitName    = optional
commonName        = supplied
emailAddress        = optional
[ req ]
default_bits        = 2048
default_md        = sha256
default_keyfile     = privkey.pem
distinguished_name    = req_distinguished_name
attributes        = req_attributes
x509_extensions    = v3_ca    # The extentions to add to the self signed cert
string_mask = utf8only
[ req_distinguished_name ]
countryName            = Country Name (2 letter code)
countryName_default        = XX
countryName_min            = 2
countryName_max            = 2
stateOrProvinceName        = State or Province Name (full name)
localityName            = Locality Name (eg, city)
localityName_default        = Default City
0.organizationName        = Organization Name (eg, company)
0.organizationName_default    = Default Company Ltd
organizationalUnitName        = Organizational Unit Name (eg, section)
commonName            = Common Name (eg, your name or your server\'s hostname)
commonName_max            = 64
emailAddress            = Email Address
emailAddress_max        = 64
[ req_attributes ]
challengePassword        = A challenge password
challengePassword_min        = 4
challengePassword_max        = 20
unstructuredName        = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment            = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
[ crl_ext ]
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
basicConstraints=CA:FALSE
nsComment            = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
[ tsa ]
default_tsa = tsa_config1    # the default TSA section
[ tsa_config1 ]
dir        = ./demoCA        # TSA root directory
serial        = $dir/tsaserial    # The current serial number (mandatory)
crypto_device    = builtin        # OpenSSL engine to use for signing
signer_cert    = $dir/tsacert.pem     # The TSA signing certificate
                    # (optional)
certs        = $dir/cacert.pem    # Certificate chain to include in reply
                    # (optional)
signer_key    = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy    = tsa_policy1        # Policy if request did not specify it
                    # (optional)
other_policies    = tsa_policy2, tsa_policy3    # acceptable policies (optional)
digests        = sha1, sha256, sha384, sha512    # Acceptable message digests (mandatory)
accuracy    = secs:1, millisecs:500, microsecs:100    # (optional)
clock_precision_digits  = 0    # number of digits after dot. (optional)
ordering        = yes    # Is ordering defined for timestamps?
                # (optional, default: no)
tsa_name        = yes    # Must the TSA name be included in the reply?
                # (optional, default: no)
ess_cert_id_chain    = no    # Must the ESS cert id chain be included?
                # (optional, default: no)

 

posted @ 2020-08-21 17:49  Boks  阅读(2350)  评论(0编辑  收藏  举报