1. Using the x509 module
openssl x509 ...
...
2 Using the ca module
openssl ca ...
...
你错过了这些命令的前奏。
这是一个两步的过程。首先设置CA,然后签署最终实体证书(也就是服务器或用户)。这两个命令都将这两个步骤简化为一个步骤。这两种方法都假设您已经为ca和服务器(终端实体)证书设置了OpenSSL配置文件。
首先,创建一个基本配置文件:
$ touch openssl-ca.cnf
然后,添加以下内容:
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
default_days = 365 # How long to certify for
default_crl_days = 30 # How long before next CRL
default_md = sha256 # Use public key default MD
preserve = no # Keep passed DN ordering
x509_extensions = ca_extensions # The extensions to add to the cert
email_in_dn = no # Don't concat the email in the DN
copy_extensions = copy # Required to copy SANs from CSR to cert
####################################################################
[ req ]
default_bits = 4096
default_keyfile = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions = ca_extensions
string_mask = utf8only
####################################################################
[ ca_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Maryland
localityName = Locality Name (eg, city)
localityName_default = Baltimore
organizationName = Organization Name (eg, company)
organizationName_default = Test CA, Limited
organizationalUnitName = Organizational Unit (eg, division)
organizationalUnitName_default = Server Research Department
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test CA
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ ca_extensions ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
basicConstraints = critical, CA:true
keyUsage = keyCertSign, cRLSign
上面的字段取自更复杂的openssl.cnf(您可以在/usr/lib/openssl.cnf中找到它),但我认为它们是创建CA证书和私钥的必要条件。
根据你的喜好调整上面的字段。默认设置为您节省了在尝试配置文件和命令选项时输入相同信息的时间。
我省略了与crl相关的内容,但是您的CA操作应该包含这些内容。请参阅openssl.cnf和相关的crl_ext部分。
然后执行以下操作。nodes省略了密码或密码短语,以便您可以检查证书。省略密码或密码短语是一个非常糟糕的主意。
$ openssl req -x509 -config openssl-ca.cnf -days 365 -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
命令执行后,执行cacert。pem将是CA操作的证书。Pem是私钥。请记住,私钥没有密码或密码短语。
您可以使用以下方法转储证书。
$ openssl x509 -in cacert.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 11485830970703032316 (0x9f65de69ceef2ffc)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com
Validity
Not Before: Jan 24 14:24:11 2014 GMT
Not After : Feb 23 14:24:11 2014 GMT
Subject: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:b1:7f:29:be:78:02:b8:56:54:2d:2c:ec:ff:6d:
...
39:f9:1e:52:cb:8e:bf:8b:9e:a6:93:e1:22:09:8b:
59:05:9f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A
X509v3 Authority Key Identifier:
keyid:4A:9A:F3:10:9E:D7:CF:54:79:DE:46:75:7A:B0:D0:C1:0F:CF:C1:8A
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage:
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
4a:6f:1f:ac:fd:fb:1e:a4:6d:08:eb:f5:af:f6:1e:48:a5:c7:
...
cd:c6:ac:30:f9:15:83:41:c1:d1:20:fa:85:e7:4f:35:8f:b5:
38:ff:fd:55:68:2c:3e:37
用以下方法测试它的目的(不要担心Any purpose:是的;参见“critical,CA:FALSE”,但“Any Purpose CA: Yes”)。
$ openssl x509 -purpose -in cacert.pem -inform PEM
Certificate purposes:
SSL client : No
SSL client CA : Yes
SSL server : No
SSL server CA : Yes
Netscape SSL server : No
Netscape SSL server CA : Yes
S/MIME signing : No
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : Yes
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIJAJ9l3mnO7y/8MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV
...
aQUtFrV4hpmJUaQZ7ySr/RjCb4KYkQpTkOtKJOU1Ic3GrDD5FYNBwdEg+oXnTzWP
tTj//VVoLD43
-----END CERTIFICATE-----
对于第二部分,我将创建另一个易于理解的配置文件。首先,访问openssl-server.cnf(您也可以为用户证书创建一个这样的文件)。
$ touch openssl-server.cnf
然后打开它,并添加以下内容。
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ req ]
default_bits = 2048
default_keyfile = serverkey.pem
distinguished_name = server_distinguished_name
req_extensions = server_req_extensions
string_mask = utf8only
####################################################################
[ server_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = MD
localityName = Locality Name (eg, city)
localityName_default = Baltimore
organizationName = Organization Name (eg, company)
organizationName_default = Test Server, Limited
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test Server
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ server_req_extensions ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
####################################################################
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
如果你正在开发并且需要使用你的工作站作为服务器,那么你可能需要为Chrome做以下操作。否则Chrome可能会抱怨一个公共名称是无效的(ERR_CERT_COMMON_NAME_INVALID)。在这个例子中,我不确定SAN中的IP地址和CN之间的关系。
# IPv4 localhost
IP.1 = 127.0.0.1
# IPv6 localhost
IP.2 = ::1
然后,创建服务器证书请求。请务必省略-x509*。添加-x509将创建一个证书,而不是一个请求。
$ openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM
执行此命令后,您将在servercert中拥有一个请求。CSR和serverkey.pem中的私钥。
你可以再检查一遍。
$ openssl req -text -noout -verify -in servercert.csr
Certificate:
verify OK
Certificate Request:
Version: 0 (0x0)
Subject: C=US, ST=MD, L=Baltimore, CN=Test Server/emailAddress=test@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d:
...
f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51:
86:e1
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Subject Key Identifier:
1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com
Netscape Comment:
OpenSSL Generated Certificate
Signature Algorithm: sha256WithRSAEncryption
6d:e8:d3:85:b3:88:d4:1a:80:9e:67:0d:37:46:db:4d:9a:81:
...
76:6a:22:0a:41:45:1f:e2:d6:e4:8f:a1:ca:de:e5:69:98:88:
a9:63:d0:a7
接下来,您必须与您的CA签署它。
您几乎已经准备好由CA对服务器证书进行签名了。CA的openssl-ca.cnf在发出命令之前还需要两个部分。
首先,打开openssl-ca.cnf并添加以下两个部分。
####################################################################
[ signing_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ signing_req ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
其次,将以下内容添加到openssl-ca.cnf的[CA_default]部分。我在前面省略了它们,因为它们会使事情复杂化(当时没有使用它们)。现在你将看到它们是如何使用的,所以希望它们是有意义的。
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Set to 'no' to allow creation of
# several certificates with same subject.
第三,触摸index.txt和serial.txt:
$ touch index.txt
$ echo '01' > serial.txt
然后执行以下操作:
$ openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr
你应该看到类似下面的内容:
Using configuration from openssl-ca.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :ASN.1 12:'MD'
localityName :ASN.1 12:'Baltimore'
commonName :ASN.1 12:'Test CA'
emailAddress :IA5STRING:'test@example.com'
Certificate is to be certified until Oct 20 16:12:39 2016 GMT (1000 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
执行该命令后,您将在servercert.pem中拥有一个新生成的服务器证书。私钥已经创建,在serverkey.pem中。
最后,您可以使用以下方法检查新生成的证书:
$ openssl x509 -in servercert.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 9 (0x9)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=MD, L=Baltimore, CN=Test CA/emailAddress=test@example.com
Validity
Not Before: Jan 24 19:07:36 2014 GMT
Not After : Oct 20 19:07:36 2016 GMT
Subject: C=US, ST=MD, L=Baltimore, CN=Test Server
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ce:3d:58:7f:a0:59:92:aa:7c:a0:82:dc:c9:6d:
...
f9:5e:0c:ba:84:eb:27:0d:d9:e7:22:5d:fe:e5:51:
86:e1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
1F:09:EF:79:9A:73:36:C1:80:52:60:2D:03:53:C7:B6:BD:63:3B:61
X509v3 Authority Key Identifier:
keyid:42:15:F2:CA:9C:B1:BB:F5:4C:2C:66:27:DA:6D:2E:5F:BA:0F:C5:9E
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com
Netscape Comment:
OpenSSL Generated Certificate
Signature Algorithm: sha256WithRSAEncryption
b1:40:f6:34:f4:38:c8:57:d4:b6:08:f7:e2:71:12:6b:0e:4a:
...
45:71:06:a9:86:b6:0f:6d:8d:e1:c5:97:8d:fd:59:43:e9:3c:
56:a5:eb:c8:7e:9f:6b:7a
前面,您向CA_default添加了以下内容:copy_extensions = copy。这复制了由提出请求的人提供的扩展名。
如果您省略了copy_extensions = copy,那么您的服务器证书将缺少主题替代名称(SANs),例如www.example.com和mail.example.com。
如果您使用copy_extensions = copy,但不查看请求,那么请求者可能会欺骗您为从属根(而不是服务器或用户证书)之类的东西签名。这意味着他/她将能够生成链接回您的受信任根目录的证书。请确保在签名之前使用openssl req -verify验证请求。
如果省略unique_subject或将其设置为yes,则只允许在主题的唯一名称下创建一个证书。
unique_subject = yes # Set to 'no' to allow creation of
# several ctificates with same subject.
在尝试创建第二个证书时,当使用CA的私钥签署服务器证书时,将导致以下结果:
Sign the certificate? [y/n]:Y
failed to update database
TXT_DB error number 2
因此unique_subject = no非常适合测试。
如果您希望确保自签名CA、从属CA和最终实体证书之间的“组织名称”一致,则需要在CA配置文件中添加以下内容:
[ policy_match ]
organizationName = match
如果您想允许组织名称更改,请使用:
[ policy_match ]
organizationName = supplied
还有其他关于在X.509/PKIX证书中处理DNS名称的规则。有关规则请参阅这些文件:
RFC 5280, Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
RFC 6125, Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)
RFC 6797, Appendix A, HTTP Strict Transport Security (HSTS)
RFC 7469, Public Key Pinning Extension for HTTP
CA/Browser Forum Baseline Requirements
CA/Browser Forum Extended Validation Guidelines
列出RFC 6797和RFC 7469,是因为它们比其他RFC和CA/B文档更具限制性。RFC的6797和7469也不允许IP地址。