很简单地表述一下需求,就是希望一个证书能给多个域名使用(非通配符证书).

直接上脚本吧,第一个是生成根CA的证书,因为是在以前的基础上完成的,所以实际是将就自己以前写的一个多级CA签发证书的脚本做的。原文见这里。

[这里](http://blog.chinaunix.net/uid-20553497-id-3163297.html)pm@debian:~/test/ca$ cat
makerootca.sh
#!/bin/bashDI
R=`pwd`mkdir -p $DIR/demoCA/privatemkdir -p $DIR/demoCA/newcertsmkdir -p $DIR/autogettouch $DIR/demoCA/index.txt
echo 01 > $DIR/demoCA/serial
openssl genrsa -des3 -out $DIR/demoCA/private/cakey.pem
2048
openssl req -new -x509 -days 3650 -key $DIR/demoCA/private/cakey.pem
-out $DIR/demoCA/careq.pem

然后是签发二级CA的脚本

pm@debian:~/test/ca$ cat no2ca.sh

#!/bin/bashNAM
E=$
1DIR=$(pwd)/autoget
openssl genrsa -des3 -out $DIR/$NAME.key 2048
openssl rsa -in $DIR/$NAME.key -out $DIR/$NAME.key
openssl req -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr
openssl ca -extensions v3_ca -in $DIR/$NAME.csr -confi
g ./openssl.cnf -days 3000 -out $DIR/$NAME.crt
-cert $DIR/../demoCA/careq.pem
-keyfi
le $DIR/../demoCA/private/cakey.pem

对应的配置文件是

openssl.cnf文件:

HOME = .RANDFILE = $ENV::HOME/.rndoid_section = new_oids[ new_oids ]tsa_policy1 = 1.2.3.4.1tsa_policy2 = 1.2.3.4.5.6tsa_policy3 = 1.2.3.4.5.7[ ca ]default_ca = CA_default # The default ca section[ CA_default ]dir = ./demoCA # Where everything is keptcerts = $dir/certs # Where the issued certs are keptcrl_dir = $dir/crl # Where the issued crl are keptdatabase = $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 certificateserial = $dir/serial # The current serial numbercrlnumber = $dir/crlnumber # the current crl number# must be commented out to leave a V1 CRLcrl = $dir/crl.pem # The current CRLprivate_key = $dir/private/cakey.pem # The private keyRANDFILE = $dir/private/.rand # private random number filex509_extensions = usr_cert # The extentions to add to the certname_opt = ca_default # Subject Name optionscert_opt = ca_default # Certificate field optionsdefault_days = 365 # how long to certify fordefault_crl_days= 30 # how long before next CRLdefault_md = default # use public key default MDpreserve = no # keep passed DN orderingpolicy = policy_match[ policy_match ]countryName = matchstateOrProvinceName = matchorganizationName = optionalorganizationalUnitName = optionalcommonName = suppliedemailAddress = optional[ policy_anything ]countryName = optionalstateOrProvinceName = optionallocalityName = optionalorganizationName = optionalorganizationalUnitName = optionalcommonName = suppliedemailAddress = optional[ req ]default_bits = 2048default_keyfile = privkey.pemdistinguished_name = req_distinguished_nameattributes = req_attributesx509_extensions = v3_ca # The extentions to add to the self signed certstring_mask = utf8only[ req_distinguished_name ]countryName = Country Name (2 letter code)countryName_default = AUcountryName_min = 2countryName_max = 2stateOrProvinceName = State or Province Name (full name)stateOrProvinceName_default = Some-StatelocalityName = Locality Name (eg, city)0.organizationName = Organization Name (eg, company)0.organizationName_default = Internet Widgits Pty LtdorganizationalUnitName = Organizational Unit Name (eg, section)commonName = Common Name (e.g. server FQDN or YOUR name)commonName_max = 64emailAddress = Email AddressemailAddress_max = 64[ req_attributes ]challengePassword = A challenge passwordchallengePassword_min = 4challengePassword_max = 20unstructuredName = An optional company name[ usr_cert ]basicConstraints=CA:FALSEnsComment = “OpenSSL Generated Certificate”subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuer[ v3_req ]basicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEncipherment[ v3_ca ]subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid:always,issuerbasicConstraints = CA:true[ crl_ext ]authorityKeyIdentifier=keyid:always[ proxy_cert_ext ]basicConstraints=CA:FALSEnsComment = “OpenSSL Generated Certificate”subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuerproxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo[ tsa ]default_tsa = tsa_config1 # the default TSA section[ tsa_config1 ]dir = ./demoCA # TSA root directoryserial = $dir/tsaserial # The current serial number (mandatory)crypto_device = builtin # OpenSSL engine to use for signingsigner_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 = md5, sha1 # 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)

openssl1.cnf

HOME = .RANDFILE = $ENV::HOME/.rndoid_section = new_oids[ new_oids ]tsa_policy1 = 1.2.3.4.1tsa_policy2 = 1.2.3.4.5.6tsa_policy3 = 1.2.3.4.5.7[ ca ]default_ca = CA_default # The default ca section[ CA_default ]dir = ./demoCA # Where everything is keptcerts = $dir/certs # Where the issued certs are keptcrl_dir = $dir/crl # Where the issued crl are keptdatabase = $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 certificateserial = $dir/serial # The current serial numbercrlnumber = $dir/crlnumber # the current crl number# must be commented out to leave a V1 CRLcrl = $dir/crl.pem # The current CRLprivate_key = $dir/private/cakey.pem # The private keyRANDFILE = $dir/private/.rand # private random number filex509_extensions = usr_cert # The extentions to add to the certname_opt = ca_default # Subject Name optionscert_opt = ca_default # Certificate field optionsdefault_days = 365 # how long to certify fordefault_crl_days= 30 # how long before next CRLdefault_md = default # use public key default MDpreserve = no # keep passed DN orderingpolicy = policy_match[ policy_match ]countryName = matchstateOrProvinceName = matchorganizationName = optionalorganizationalUnitName = optionalcommonName = suppliedemailAddress = optional[ policy_anything ]countryName = optionalstateOrProvinceName = optionallocalityName = optionalorganizationName = optionalorganizationalUnitName = optionalcommonName = suppliedemailAddress = optional[ req ]default_bits = 2048default_keyfile = privkey.pemdistinguished_name = req_distinguished_nameattributes = req_attributesx509_extensions = v3_ca # The extentions to add to the self signed certstring_mask = utf8only[ req_distinguished_name ]countryName = Country Name (2 letter code)countryName_default = AUcountryName_min = 2countryName_max = 2stateOrProvinceName = State or Province Name (full name)stateOrProvinceName_default = Some-StatelocalityName = Locality Name (eg, city)0.organizationName = Organization Name (eg, company)0.organizationName_default = Internet Widgits Pty LtdorganizationalUnitName = Organizational Unit Name (eg, section)0.commonName = Common Name1 (e.g. server FQDN or YOUR name1)0.commonName_max = 641.commonName = Common Name2 (e.g. server FQDN or YOUR name2)1.commonName_max = 642.commonName = Common Name3 (e.g. server FQDN or YOUR name2)2.commonName_max = 643.commonName = Common Name3 (e.g. server FQDN or YOUR name2)3.commonName_max = 64emailAddress = Email AddressemailAddress_max = 64[ req_attributes ]challengePassword = A challenge passwordchallengePassword_min = 4challengePassword_max = 20unstructuredName = An optional company name[ usr_cert ]basicConstraints=CA:FALSEnsComment = “OpenSSL Generated Certificate”subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuer[ v3_req ]basicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEncipherment[ v3_ca ]subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid:always,issuerbasicConstraints = CA:true[ crl_ext ]authorityKeyIdentifier=keyid:always[ proxy_cert_ext ]basicConstraints=CA:FALSEnsComment = “OpenSSL Generated Certificate”subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuerproxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo[ tsa ]default_tsa = tsa_config1 # the default TSA section[ tsa_config1 ]dir = ./demoCA # TSA root directoryserial = $dir/tsaserial # The current serial number (mandatory)crypto_device = builtin # OpenSSL engine to use for signingsigner_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 = md5, sha1 # 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)

测试了一下,chrome和firefox只能查看最后一个证书 。

========================================

然后就尝试签发有subjectAltName的证书。

对于no4domain.sh 脚本,制定使用的extension配置段,比如v3_ca

pm@debian:~/test/ca$ cat no4domain.sh |grep -v “^#”[ $# -ne 1 ] &&
echo “$0 NAME” && exitNAME=$1DIR=$(pwd)/autogetopenssl genrsa -des3 -out $DIR/$NAME.key 2048openssl rsa -in $DIR/$NAME.key -out $DIR/$NAME.keyopenssl req -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr -config ./openssl2.cnfopenssl ca -in $DIR/$NAME.csr -extensionsv3_ca-config ./openssl2.cnf -days 3650 -out $DIR/$NAME.crt -cert $DIR/no3.crt -keyfile $DIR/no3.key
这时就可以使用这个证书给多个域名使用了。使用curl的时候可以看到提示subjectAltName matched。