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)