如何与证书颁发机构签署证书签署请求?

在我的搜索过程中,我发现了签署SSL证书签名请求的几种方法:

  1. 使用x509模块:

    openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
    
  2. Using the ca module:

    openssl ca -cert ca.crt -keyfile ca.key -in server.csr -out server.crt
    

Note: I am unsure of the use of the right parameters for this one. Please advise correct usage if I am to use it.

What way should one use to sign certificate requests with your Certification Authority? Is one method better than the other (for example, one being deprecated)?

394643 次浏览
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 -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

命令执行后,cacert.pem将是用于CA操作的证书,而cakey.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: Yes;见“关键,CA: FALSE"任何目的CA:是的;)。

$ 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-----

对于第二部分,我将创建另一个易于理解的配置文件。首先,touch 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可能会抱怨Common Name无效(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.txtserial.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,那么你的服务器证书将缺少主题替代名称(san),比如www.example.commail.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、下属CAEnd-Entity证书之间的组织的名字是一致的,那么将以下内容添加到CA配置文件中:

[ policy_match ]
organizationName = match

如果你想允许组织的名字改变,那么使用:

[ policy_match ]
organizationName = supplied

还有其他关于在X.509/PKIX证书中处理DNS名称的规则。有关规则请参阅这些文件:

列出RFC 6797和RFC 7469,是因为它们比其他RFC和CA/B文档更具限制性。RFC的6797和7469 也允许一个IP地址。

除了@jww的答案,我想说的是openssl-ca.cnf中的配置,

default_days     = 1000         # How long to certify for

定义由此根ca签名的证书的默认有效天数。要设置root-ca本身的有效性,你应该在下面使用'-days n'选项:

openssl req -x509 -days 3000 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

如果不这样做,您的根CA的有效期将仅为默认的一个月,由该根CA签署的任何证书的有效期也将为一个月。

有时,例如用于测试,您只是想要一种简单的方法来生成签名证书,而不需要设置完整的CA配置。仅使用openssl reqopenssl x509命令就可以做到这一点。您永远不会将此方法用于生产证书,但由于它对于一些非生产情况很有用,因此下面是命令。

生成自签名证书

首先,创建一个自签名证书,用作信任的根:

openssl req -x509 -days 365 -key ca_private_key.pem -out ca_cert.pem

或者等效地,如果你想在一个命令中生成一个私钥和一个自签名证书:

openssl req -x509 -days 365 -newkey rsa:4096 -keyout ca_private_key.pem -out ca_cert.pem

生成证书请求

接下来,为要签名的证书创建一个证书请求:

openssl req -new -key my_private_key.pem -out my_cert_req.pem

同样,如果需要,你可以同时生成私钥和请求:

openssl req -new -newkey rsa:4096 -keyout my_private_key.pem -out my_cert_req.pem

生成已签名的证书

最后,使用自签名的签名证书从证书请求生成一个签名证书:

openssl x509 -req -in my_cert_req.pem -days 365 -CA ca_cert.pem -CAkey ca_private_key.pem -CAcreateserial -out my_signed_cert.pem