具有主题备用名称的 OpenSSL 证书(版本 3)
Posted
技术标签:
【中文标题】具有主题备用名称的 OpenSSL 证书(版本 3)【英文标题】:OpenSSL Certificate (Version 3) with Subject Alternative Name 【发布时间】:2011-09-05 20:36:51 【问题描述】:我正在使用 OpenSSL 命令行工具生成自签名证书。除了两个问题外,它似乎工作正常。我无法使用 Subject Alternative Name(关键)创建 .cer
,而且我无法弄清楚如何创建 Version 3(不确定这是否很关键,但更愿意学习如何设置版本)。
有没有人成功做到这一点?默认配置 (.cfg
) 文件具有看似清晰的文档(如下所示):
这些东西是为 subjectAltName 和 issuerAltname 准备的。 导入电子邮件地址。 subjectAltName=电子邮件:复制
但是这不起作用。我的预感是主题 Alternative Name 没有出现 b/c 它不在 V1 规范中,这就是为什么我也在追求设置他的版本。
这是我正在使用的配置文件:
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
emailAddress = myEmail@email.com
req_extensions = v3_req
x509_extensions = v3_ca
[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US
C_min = 2
C_max = 2
O = [Press Enter to Continue]
O_default = default
0.OU=[Press Enter to Continue]
0.OU_default = default
1.OU=[Press Enter to Continue]
1.OU_default = PKI
2.OU=[Press Enter to Continue]
2.OU_default = ABCD
commonName = Public FQDN of server
commonName_max = 64
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName = email:myEmail@email.com
issuerAltName = issuer:copy
【问题讨论】:
【参考方案1】:我让它与以下版本一起使用(电子邮件地址放置不正确):
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_ca
[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US
C_min = 2
C_max = 2
O = [Press Enter to Continue]
O_default = default
0.OU=[Press Enter to Continue]
0.OU_default = default
1.OU=[Press Enter to Continue]
1.OU_default = PKI
2.OU=[Press Enter to Continue]
2.OU_default = ABCD
commonName = Public FQDN of server
commonName_max = 64
emailAddress = [Press Enter to Continue]
emailAddress_default = myEmail@email.com
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName = email:myEmail@email.com
issuerAltName = issuer:copy
注意事项:
生成我使用的证书:
openssl req -config req.cnf -new -nodes -out req.pem -x509
我没有看到issuerAltname
有太多用处(如果你有我很想知道在哪里)。
不建议对authorityKeyIdentifier
使用issuer:always
。
现在可以使用 email:copy
和 subjectAltName
。
v3_req
部分是多余的(以及 req_extensions
行。
【讨论】:
【参考方案2】:您使用什么命令来提出 CSR 证书请求?你用什么命令来制作证书文件?你知道的不同情况下的不同答案。
也许你没有放
subjectAltName=email:copy
在部分
[v3_req]
也许你正在使用 openssl x509 来生成证书,如果是这样你必须使用
-extfile /etc/pki/tls/openssl.cnf
因为没有它,它不会使用您的配置文件
你可能还需要
-扩展 v3_req
命令行开关
【讨论】:
【参考方案3】:下面是简单的步骤
在生成 CSR 时,您应该使用 -config
和 -extensions
在生成证书时,您应该使用-extfile
和-extensions
示例如下:
openssl req -new -nodes -keyout test.key -out test.csr -days 3650 -subj "/C=US/ST=SCA/L=SCA/O=Oracle/OU=Java/CN=test cert" -config /etc/pki/tls/openssl.cnf -extensions v3_req
openssl x509 -req -days 3650 -in test.csr -CA cacert.pem -CAkey rootCA.key -CAcreateserial -out test.pem -extfile /etc/pki/tls/openssl.cnf -extensions v3_req
希望对你有帮助
【讨论】:
我很困惑:您要在生成证书之前生成 CSR(证书签名请求)!?不是应该反过来吗? @Marc 首先需要证书签名请求。它的名字告诉你它是什么:它是一个由证书颁发机构 (CA) 签署的新证书的请求。 CA 接受该请求并为您签署/生成一个全新的证书。您不会先制作证书,然后再对其进行签名。【参考方案4】:我刚刚开发了一个web based tool,它将根据表单输入自动生成此命令并显示输出。
更新:见certificatetools.com
它变得如此受欢迎,以至于我对其进行了改进并以自己的域名发布。
它不仅会为您提供可下载的 .csr,还会提供用于生成它的 openssl 命令,以及所需的 openssl.cnf 配置选项。
示例:
OpenSSL 命令
#generate the RSA private key
openssl genpkey -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out priv.key
#Create the CSR
openssl req -new -nodes -key priv.key -config csrconfig.txt -out cert.csr
OpenSSL CSR 配置
[ req ]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = example.com
countryName = US
stateOrProvinceName = Louisiana
localityName = Slidell
organizationName = Acme Inc.
[ req_ext ]
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = @alt_names
[ alt_names ]
IP.0 = 1.1.1.1
IP.1 = 2.2.2.2
DNS.0 = server1.example.com
DNS.1 = server2.example.com
email.0 = email1@example.com
email.1 = email2@example.com
【讨论】:
这个工具很简洁,但我真的建议删除私钥的生成。如果您在您无法控制的服务器(例如托管您的工具的服务器)上生成私钥,则根据定义 不再是私有的。 我不建议在生产中使用使用此工具生成的密钥,但如果不先生成私钥,我将无法制作 CSR 或证书。该工具用于学习、测试和原型设计。在站点上完成的每项操作都会返回所有 OpenSSL 命令,因此一切都可以私下离线完成。这是该工具相对于其他工具的优势之一。 你比我更信任别人。如果它准备好有人会使用它......【参考方案5】:v3_req
是配置文件中的条目subjectAltName
所必需的。命令
openssl x509 ... -extfile openssl.cnf -extensions v3_req
将 SAN 插入到证书中。
【讨论】:
【参考方案6】:我知道这个线程有点旧,但以防万一它适用于 Windows 上的任何人,请检查文件是否为 UTF-8 编码,在我的情况下,我收到一个错误,表明 .cnf 文件存在错误,所以我在 Notepad++ 上打开它,将文件编码设置为 UTF-8,保存,然后再次运行 openssl 命令,它成功了。
【讨论】:
【参考方案7】:好的,此页面上的其他答案均不适合我,我尝试了每一个答案。对我有用的是一个小技巧:
申请证书时:
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-reqexts SAN
在签署证书时:
-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-extensions SAN
请注意,这是一个 bash 技巧,<(some comamnds)
使 some commands
的标准输出输出显示为 bash 中外部命令的临时文件。
所以没有混淆,这是一个从一开始就涵盖所有内容的工作脚本,包括创建证书颁发机构:
# if the server name is undefined, lets default to 'Some-Server'
SERVER="$SERVER:-Some-Server"
CORPORATION=My-Corp
GROUP=My-Corporate-Group
CITY=City
STATE=State
COUNTRY=US
CERT_AUTH_PASS=`openssl rand -base64 32`
echo $CERT_AUTH_PASS > cert_auth_password
CERT_AUTH_PASS=`cat cert_auth_password`
# create the certificate authority
openssl \
req \
-subj "/CN=$SERVER.ca/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
-new \
-x509 \
-passout pass:$CERT_AUTH_PASS \
-keyout ca-cert.key \
-out ca-cert.crt \
-days 36500
# create client private key (used to decrypt the cert we get from the CA)
openssl genrsa -out $SERVER.key
# create the CSR(Certitificate Signing Request)
openssl \
req \
-new \
-nodes \
-subj "/CN=$SERVER/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
-sha256 \
-extensions v3_req \
-reqexts SAN \
-key $SERVER.key \
-out $SERVER.csr \
-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-days 36500
# sign the certificate with the certificate authority
openssl \
x509 \
-req \
-days 36500 \
-in $SERVER.csr \
-CA ca-cert.crt \
-CAkey ca-cert.key \
-CAcreateserial \
-out $SERVER.crt \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-extensions SAN \
-passin pass:$CERT_AUTH_PASS
然后我们可以验证主题备用名称是否在最终证书中:
openssl x509 -in Some-Server.crt -text -noout
相关部分是:
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:Some-Server
所以它奏效了!只要您在浏览器中安装证书颁发机构,每个主要浏览器(包括 chrome)都会接受此证书。这就是您需要安装的ca-cert.crt
。
这是一个允许您使用证书的 nginx 配置示例:
server
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost:443;
ssl_certificate /etc/ssl/certs/Some-Server.crt;
ssl_certificate_key /etc/ssl/private/Some-Server.key;
ssl_dhparam /etc/ssl/certs/https-dhparam.pem;
location /
root /usr/share/nginx/html;
index index.html index.htm;
【讨论】:
不错的脚本适用于除 android 之外的任何地方。 =(当您尝试安装crt时,Android会出现以下错误“安装需要私钥” @Jack Davidson:您的脚本似乎有/bin/bash
样式的输入重定向。例如:-config <(cat [snip])
。您可能想要编辑您的答案以明确说明它是一个bash
脚本。 @Michael Hobbs:Android 上的默认 shell 可能不是 bash
。
以上,不要在-config '<(cat ...)'
中加上单引号,否则shell会将其视为文字字符串。它在脚本中正确显示。不幸的是,SO不会让我编辑。
非常好的解决方案,CA 密码仅在密钥创建期间使用,然后被丢弃。更安全,谢谢!【参考方案8】:
我参考了几页,最重要的帮助来自 1.https://geekflare.com/san-ssl-certificate/、2.https://certificatetools.com/(参见 user40662 的回答)和 3.Raghu K Nair 关于命令用法的回答。
那么我的成功尝试:
san.cnf
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName = CN # C=
stateOrProvinceName = Shanghai # ST=
localityName = Shanghai # L=
#postalCode = 200000 # L/postalcode=
#streetAddress = "My Address" # L/street=
organizationName = My Corporation # O=
organizationalUnitName = My Department # OU=
commonName = myname.mysoftware.mycorporation.com # CN=
emailAddress = myname@example.com # CN/emailAddress=
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = myname.mysoftware.mycorporation.com
#DNS.2 = other2.com
#DNS.3 = other3.com
命令:
openssl req -x509 -nodes -days 365 -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Corporation/OU=My Department/CN=myname.mysoftware.mycorporation.com/emailAddress=myname@example.com" -keyout privateKey.pem -out certificate.crt -config san.cnf -extensions v3_req
【讨论】:
【参考方案9】:#! /bin/dash
# Steps 1-3 show how to use openssl to create a certificate request
# that includes Subject Alternative Names.
# In the uncommon case where you are creating your own CA, steps 4-6
# show how to use openssl to create a CA and then use that CA to
# create a certificate from the request.
# Step 1: Create an OpenSSL configuration file
# to specify the Subject Alternative Names
echo ; echo 'step 1'
cat > foo.cnf <<EOF
[ req ]
distinguished_name = arbitrary_name_1
req_extensions = arbitrary_name_2
[ arbitrary_name_1 ]
[ arbitrary_name_2 ]
subjectAltName = @arbitrary_name_3
[ arbitrary_name_3 ]
DNS.1 = foo.com
DNS.2 = bar.com
DNS.3 = baz.com
EOF
# Step 2: Create a certificate request for foo.com.
#
# openssl
# req
# -config read openssl configuration from this file
# -subj set the commonName of the certificate
# -newkey generate a new key (and, by implication, a new request!)
# -nodes do not encrypt the new private key ("no DES")
# -keyout write the new private key to this file
# -out write the request to this file
echo ; echo 'step 2'
openssl \
req \
-config foo.cnf \
-subj '/CN=foo.com' \
-newkey rsa:2048 \
-nodes \
-keyout foo.key \
-out foo.req
# Step 3: Display the requested extensions.
echo ; echo 'step 3'
openssl req -in foo.req -noout -text | \
grep -A 2 'Requested Extensions:'
# Step 4: Create a certificate authority by creating
# a private key and self-signed certificate.
#
# openssl
# req generate a certificate request, but don't because ...
# -x509 generate a self-signed certificate instead
# -subj set the commonName of the certificate
# -days certificate is valid for N days, starting now
# -newkey generate a new private key
# -nodes do not encrypt the new private key ("no DES")
# -keyout write the new private key to this file
# -out write the self-signed certificate to this file
echo ; echo 'step 4'
openssl \
req \
-x509 \
-subj "/CN=Custom CA" \
-days 4000 \
-newkey rsa:2048 \
-nodes \
-keyout ca.key \
-out ca.cert
# Step 5: Use the certificate authority
# to create a certificate for foo.com.
#
# openssl
# x509 operate on an x509 certificate
# -req create an x509 certificate from a request
# -in read the request from this file
# -CA read the CA certificate from this file
# -CAkey read the CA key form this file
# -extfile read openssl's configuration from this file
# -extensions read extensions from this section of the configuration
# -days certificate is valid for N days, starting now
# -set_serial set the new certificate's serial number
# -out write the new certificate to this file
echo ; echo 'step 5'
openssl \
x509 \
-req \
-in foo.req \
-CA ca.cert \
-CAkey ca.key \
-extfile foo.cnf \
-extensions arbitrary_name_2 \
-days 30 \
-set_serial 1001 \
-out foo.cert
# Step 6: Display the X509v3 extensions:
echo ; echo 'step 6'
openssl x509 -in foo.cert -noout -text | \
grep -A 2 'X509v3 extensions:'
【讨论】:
我试过了,这行得通,但是使用nodes
选项(第 4 步)生成的 CA 留下了一个安全漏洞,我认为...
@Will59 - 未加密的私钥是否是“安全漏洞”取决于(IMO)您的用例和安全要求。脚本中的注释清楚地说明了-nodes
的后果。如果您需要加密的私钥,请根据需要进行调整。如果您正在创建自己的 CA,希望您有足够的背景知识来了解选择和相关后果。我的示例旨在简单易懂,并且(IMO)-nodes
比加密私钥更简单。【参考方案10】:
尽管按照此处描述的步骤操作后,我开始使用 .csr 文件: X509v3 主题备用名称 但是,我生成的 .crt (.pem) 文件是:
openssl x509 -req -in domain.csr -extensions SAN -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out domain.crt -days 100
还在一起:
Version: 1 (0x0)
和没有:
X509v3 Subject Alternative Name
解决方案
切换到这个后问题解决了:
openssl ca -in domain.csr -cert rootCA.pem -keyfile rootCA.key -out domain.crt
我开始获取 domain.crt 文件:
Version: 3 (0x2)
和
X509v3 Subject Alternative Name
如果openssl ca
抱怨,您可能需要调整openssl.cnf
(或/etc/ssl/openssl.cnf
用于ubuntu,注意:如果您使用 brew install openssl - 它将位于不同的位置)文件。只需确保正确设置这些:
[ CA_default ]
dir= /path/to/rootCA/folder # Where everything is kept
certificate= $dir/rootCA.pem # The CA certificate
serial= $dir/rootCA.srl # The current serial number
private_key= $dir/rootCA.key # The private key
然后运行: 触摸/path/to/index.txt
要生成 rootCA.srl,您仍然可以使用旧命令:
openssl x509 -req -in domain.csr -extensions SAN -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out domain.crt -days 100
更多关于openssl ca
的信息可以在这里找到:https://www.openssl.org/docs/man1.0.2/man1/ca.html
【讨论】:
以上是关于具有主题备用名称的 OpenSSL 证书(版本 3)的主要内容,如果未能解决你的问题,请参考以下文章
无法使用主题备用名称证书为 SSL/TLS 安全通道建立信任关系