我错过了什么吗?这是构建自签名证书的正确方法吗?
创建自签名证书很容易。您只需使用openssl-req命令。创建一个可供最多客户机使用的客户端(如浏览器和命令行工具)可能很棘手。
这很困难,因为浏览器有自己的一组要求,而且它们比IETF更具限制性。浏览器使用的要求记录在CA/浏览器论坛上(见下文参考资料)。限制出现在两个关键领域:(1)信任锚和(2)DNS名称。
现代浏览器(如我们在2014/2015年使用的warez)需要一个链接到信任锚的证书,他们希望DNS名称在证书中以特定方式显示。浏览器正在积极反对自签名服务器证书。
有些浏览器不太容易导入自签名服务器证书。事实上,你不能使用某些浏览器,比如Android的浏览器。因此,完整的解决方案是成为你自己的权威。
在没有成为自己的权威机构的情况下,您必须获得正确的DNS名称,以使证书获得最大的成功机会。但我鼓励你成为自己的权威。成为你自己的权威很容易,它会回避所有的信任问题(谁比你自己更值得信任?)。
这可能不是你要找的网站!站点的安全证书不受信任!
这是因为浏览器使用预定义的信任锚点列表来验证服务器证书。自签名证书不会链接回受信任的锚点。
避免这种情况的最佳方法是:
创建自己的权限(即成为CA)为服务器创建证书签名请求(CSR)使用CA密钥签署服务器的CSR在服务器上安装服务器证书在客户端上安装CA证书
第1步-创建您自己的授权仅意味着使用CA创建自签名证书:正确且正确的密钥使用。这意味着Subject和Issuer是同一实体,CA在基本约束中设置为true(也应标记为关键),密钥用法为keyCertSign和crlSign(如果您使用的是CRL),Subject key Identifier(SKI)与Authority key Identifier相同。
要成为自己的证书颁发机构,请参阅*如何与证书颁发机构签署证书签名请求?堆栈溢出。然后,将CA导入浏览器使用的信任存储。
步骤2-4大致上是您现在为面向公共的服务器注册像Startcom或CAcert这样的CA服务时所做的。第1步和第5步允许您避开第三方权威机构,充当自己的权威机构(谁比自己更值得信任?)。
避免浏览器警告的第二个最佳方法是信任服务器的证书。但有些浏览器,比如Android的默认浏览器,不允许你这样做,所以它永远不会在平台上运行。
浏览器(和其他类似的用户代理)不信任自签名证书的问题将是物联网(IoT)中的一个大问题。例如,当你连接到恒温器或冰箱来编程时,会发生什么?答案是,就用户体验而言,没有什么好东西。
W3C的WebAppSec工作组正在着手研究这个问题。例如,请参阅提案:将HTTP标记为非安全。
如何使用OpenSSL创建自签名证书
下面的命令和配置文件创建自签名证书(它还向您展示了如何创建签名请求)。它们在一个方面与其他答案不同:用于自签名证书的DNS名称是主题备用名称(SAN),而不是通用名称(CN)。
DNS名称通过配置文件以subjectAltName=@alternate_names行(无法通过命令行执行)放置在SAN中。然后在配置文件中有一个alternate_name部分(您应该根据自己的喜好进行调整):
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# IP.1 = 127.0.0.1
# IP.2 = ::1
将DNS名称放在SAN中而不是CN中是很重要的,因为IETF和CA/浏览器论坛都指定了这种做法。它们还指定CN中的DNS名称已弃用(但并非禁止)。如果在CN中输入DNS名称,则必须根据CA/B策略将其包含在SAN中。因此,您不能避免使用主题备用名称。
如果您没有将DNS名称放在SAN中,则证书将无法在浏览器和其他用户代理下验证,这些用户代理遵循CA/浏览器论坛指南。
相关:浏览器遵循CA/浏览器论坛政策;而不是IETF策略。这也是使用OpenSSL创建的证书(通常遵循IETF)有时无法在浏览器下验证(浏览器遵循CA/B)的原因之一。它们是不同的标准,它们有不同的发布政策和不同的验证要求。
创建自签名证书(注意添加了-x509选项):
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
创建签名请求(请注意缺少-x509选项):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
打印自签名证书:
openssl x509 -in example-com.cert.pem -text -noout
打印签名请求:
openssl req -in example-com.req.pem -text -noout
配置文件(通过-config选项传递)
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY
localityName = Locality Name (eg, city)
localityName_default = New York
organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company
emailAddress = Email Address
emailAddress_default = test@example.com
# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1
# IPv6 localhost
# DNS.8 = ::1
您可能需要为Chrome执行以下操作。否则,Chrome可能会投诉公用名无效(ERR_CERT_Common_Name_invalid)。我不确定SAN中的IP地址与本例中的CN之间的关系。
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
关于X.509/PKIX证书中DNS名称的处理,还有其他规则。有关规则,请参阅以下文件:
RFC 5280,Internet X.509公钥基础结构证书和证书吊销列表(CRL)配置文件RFC 6125,在传输层安全性(TLS)环境中使用X.509(PKIX)证书在互联网公钥基础设施中表示和验证基于域的应用服务身份RFC 6797,附录A,HTTP严格传输安全(HSTS)RFC 7469,HTTP公钥锁定扩展CA/浏览器论坛基线要求CA/浏览器论坛扩展验证指南
列出了RFC 6797和RFC 7469,因为它们比其他RFC和CA/B文档更具限制性。RFC 6797和7469也不允许IP地址。