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

使用x509模块: Openssl x509 -req -days 360 -in服务器。csr -CA ca.crt -CAkey ca.key - cacreateseri -out server.crt 使用ca模块: Openssl ca -cert ca.crt -keyfile ca.key -in server。-out server.crt

注意:我不确定是否使用了正确的参数。如果我要使用它,请告诉我正确的用法。

应使用何种方式向证书颁发机构签署证书请求? 是否有一种方法比另一种更好(例如,一种方法被弃用了)?


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地址。


除了@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 req和openssl 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