我正在创建两个简单的证书;一个是根证书,另一个是服务器证书。后者分别在标志和中分配了rootcert.pem
和。我已经在系统中安装了根证书并运行了。经过多次尝试,我无法使用 openssl 来根据自签名证书验证服务器证书。它给了我这个错误:rootprivkey.pem
-CA
CAkey
sudo update-cacertificates
error 20 at 0 depth lookup: unable to get local issuer certificate
error servercrt.pem: verification failed
注意:我没有中级证书。
现在,我该如何解决这个问题?
编辑:
用于生成和验证的命令
openssl req -new -newkey rsa:4096 -keyout rootprivkey.pem -out rootreq.pem -config openssl.cnf -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
openssl ca -out rootcrt.pem -days 2652 -keyfile rootprivkey.pem -selfsign -config openssl.cnf -infiles rootreq.pem
openssl req -new -newkey rsa:4096 -keyout serverprivkey.pem -out serverreq.pem -config openssl.cnf
openssl x509 -req -in serverreq.pem -days 1200 -CA rootcrt.pem -CAkey rootprivkey.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out servercrt.pem -set_serial 01
openssl verify -CAfile rootcrt.pem servercrt.pem
openssl.cnf
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# You might want to copy this into /etc/ssl/ or define OPENSSL_CONF
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
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 = . # Where everything is kept
certs = $dir # Where the issued certs are kept
crldir = $dir # Where the issued crl are kept
database = $dir # database index file.
unique_subject = yes # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $certs # default place for new certs.
certificate = $certs/rootcrt.pem # The CA certificate
serial = $dir/serial.txt # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $crldir/crl.pem # The current CRL
private_key = $dir/private/rootprivkey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
#x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 4096
default_keyfile = priv.key.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
req_extensions = v3_req
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default =
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default =
localityName = Locality Name (eg, city)
localityName_default =
0.organizationName = Organization Name (eg, company)
0.organizationName_default =
# SET-ex3 = SET extension number 3
[ req_attributes ]
#challengePassword = A challenge password
#challengePassword_min = 4
#challengePassword_max = 20
#unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true
答案1
上述配置文件无法生成根 CA 证书,因为它没有条目CommonName
。我假设这是打字错误或复制/粘贴错误,配置文件的其余部分才是实际使用的。
您的证书验证失败,因为您的根 CA 将BasicConstraint
扩展名设置为CA:False
。也就是说,它是不是CA,因此就验证而言,不能用于验证其他证书上的数字签名。
您需要修改配置文件,以便用于生成 CA 证书的命令使用:basicConstraints = CA:true
。为了使其符合 RFC 5280 标准,您还应该添加批判的标记并使用basicConstraints = critical,CA:true
。
您的方法有些脱节。请尝试以下操作:
为 CA 创建 OpenSSL 配置文件 ( ./openssl.cnf
)
################ Req Section ################
# This is used by the `openssl req` command
# to create a certificate request
[ req ]
# Don't prompt for the DN, use configured values instead
# This saves having to type in your DN each time.
prompt = no
string_mask = default
distinguished_name = req_dn
# The size of the keys in bits:
default_bits = 4096
# The extensions added when generating a CSR
req_extensions = req_ext
[ req_dn ]
countryName = GB
stateOrProvinceName = Somewhere
organizationName = Example
organizationalUnitName = PKI
commonName = Example Test Root CA
[ req_ext ]
# Extensions added to the request
################ CA Section ################
# This is used with the 'openssl ca' command
# to sign a request
[ ca ]
default_ca = CA
[ CA ]
# Where OpenSSL stores information
dir = . # Where everything is kept
certs = $dir # Where the issued certs are kept
crldir = $dir # Where the issued crl are kept
new_certs_dir = $certs
database = $dir/index
certificate = $certs/rootcrt.pem
private_key = $dir/rootprivkey.pem
crl = $crldir/crl.pem
serial = $dir/serial.txt
RANDFILE = $dir/.rand
# How OpenSSL will display certificate after signing
name_opt = ca_default
cert_opt = ca_default
# How long the CA certificate is valid for
default_days = 3650
# default_startdate = 180517000000Z
# default_enddate = 181231235959Z
# The message digest for self-signing the certificate
# sha1 or sha256 for best compatability, although most
# OpenSSL digest algorithm can be used.
# md4,md5,mdc2,rmd160,sha1,sha256
default_md = sha256
# Subjects don't have to be unique in this CA's database
unique_subject = no
# What to do with CSR extensions
copy_extensions = copy
# Rules on mandatory or optional DN components
policy = simple_policy
# Extensions added while singing with the `openssl ca` command
x509_extensions = x509_ext
[ simple_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
domainComponent = optional
emailAddress = optional
name = optional
surname = optional
givenName = optional
dnQualifier = optional
[ ca_ext ]
# Optional extensions. Use `-extensions ca_ext`
# These extensions are for a CA certificate
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
basicConstraints = critical, CA:TRUE
# basicConstraints = critical, CA:TRUE, pathlen:1
keyUsage = critical, keyCertSign, cRLSign
# Policies and constraints are not recommended for Root CAs
# But could be enforced on subordinate CAs
#nameConstraints = permitted;DNS:example.org
#policyConstraints = requireExplicitPolicy:1
#inhibitAnyPolicy = 1
#certificatePolicies = @CertPol
[ x509_ext ]
#Default extensions
# These extensions are for an end-entity certificate
# Extensions added when using the `openssl ca` command.
# This section is pointed to by `x509_extensions` above.
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# No basicConstraints extension is equal to CA:False
# basicConstraints = critical, CA:False
keyUsage = critical, digitalSignature
# Policies and constraints are not recommended for Root CAs
# But could be enforced on subordinate CAs
#nameConstraints = permitted;DNS:example.org
#policyConstraints = requireExplicitPolicy:1
#inhibitAnyPolicy = 1
#certificatePolicies = @CertPol
[ CertPol ]
policyIdentifier = 1.3.6.1.4.132473
CPS = http://pki.example.org/cps.html
接下来,使用与您之前使用的命令类似的命令创建您的请求:
$ openssl req -new -newkey rsa:4096 -keyout rootprivkey.pem -out rootreq.pem -config openssl.cnf
请注意,-sigopt
选项已被删除,因为此时的签名是用于证明拥有私钥的请求签名,并且不是证书本身的签名-那是稍后的事。
接下来,对其进行签名以创建自签名 CA 证书:
$ openssl ca -out rootcrt.pem -days 2652 -keyfile rootprivkey.pem -selfsign -config openssl.cnf -extensions ca_ext -in rootreq.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1
请注意,这使用的是openssl ca
而不是 ,openssl x509
这意味着您可以引用自定义openssl.cnf
文件。还请注意使用选项-extensions
将命令指向配置文件的特定部分。最后,请注意,选项-sigopt
已移至此处,因为这是签署 CA 证书的命令,因此应该具有您的 PSS 方案。
接下来,为您的服务器/最终实体证书 (./server.cnf) 创建一个单独的 OpenSSL 配置文件。
# OpenSSL server/end-entity configuration
[ req ]
string_mask = default
# The size of the keys in bits:
default_bits = 2048
distinguished_name = req_dn
req_extensions = req_ext
[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default =
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default =
localityName = Locality Name (eg, city)
localityName_default =
0.organizationName = Organization Name (eg, company)
0.organizationName_default =
commonName = Common Name
[ req_ext ]
# Careful...
#basicConstraints=critical,CA:TRUE
# subjectAltName = @alt_names
[alt_names]
# To copy the CN (in the case of a DNS name in the CN) use:
# DNS = ${req_dn::commonName}
运行与您使用的命令类似的命令,但配置文件已更改。
$ openssl req -new -newkey rsa:4096 -keyout serverprivkey.pem -out serverreq.pem -config server.cnf
最后,用CA签名:
$ openssl ca -in serverreq.pem -days 1200 -cert rootcrt.pem -keyfile rootprivkey.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out servercrt.pem -config openssl.cnf
请注意,这一个上没有选项,所以 OpenSSL 默认使用 中的选项-extensions
指向的部分。x509_extensions =
openssl.cnf
您现在可以验证证书:
$ openssl verify -CAfile rootcrt.pem servercrt.pem
servercrt.pem: OK