我正在为嵌入式Linux设备添加HTTPS支持。我已尝试使用以下步骤生成自签名证书:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

这是可行的,但我在Google Chrome上遇到了一些错误:

这可能不是你要找的网站!站点的安全证书不受信任!

我错过了什么吗?这是构建自签名证书的正确方法吗?


当前回答

openssl允许通过单个命令(-newkey)生成自签名证书指示生成私钥,-x509指示发出自签名证书而不是签名请求)::

openssl req -x509 -newkey rsa:4096 \
-keyout my.key -passout pass:123456 -out my.crt \
-days 365 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

您可以在单独的步骤中生成私钥和构造自签名证书:

openssl genrsa -out my.key -passout pass:123456 2048

openssl req -x509 \
-key my.key -passin pass:123456 -out my.csr \
-days 3650 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

查看生成的证书:

openssl x509 -text -noout -in my.crt

Java keytool创建PKCS#12存储::

keytool -genkeypair -keystore my.p12 -alias master \
-storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \
-storepass 123456 \
-dname "CN=localhost,O=home,C=US" \
-ext 'san=dns:localhost,dns:web.internal,email:me@mail.internal'

要导出自签名证书,请执行以下操作:

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456

查看生成的证书:

keytool -printcert -file my.crt

GnuTLS的certtool不允许从CLI传递不同的属性。我不喜欢乱搞配置文件((

其他回答

以下是@diegows的答案中描述的选项,在文档中有更详细的描述:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

请求PKCS#10证书请求和证书生成实用程序。-2009年5月此选项输出自签名证书,而不是证书请求。这通常用于生成测试证书或自签名根CA。-新密钥参数此选项创建新的证书请求和新的私钥。争论采取多种形式之一。rsa:nbits,其中nbits是位数,生成大小为n位的RSA密钥。-键入文件名这提供了用于写入新创建的私钥的文件名。-输出文件名默认情况下,指定要写入的输出文件名或标准输出。-第n天当使用-x509选项时,指定要验证的天数的证书。默认值为30天。-节点如果指定了此选项,则如果创建了私钥,则不会对其进行加密。

文件实际上比上述更详细;我只是在这里总结了一下。

正如已经详细讨论过的,自签名证书不受Internet信任。您可以将自签名证书添加到许多浏览器,但不是所有浏览器。或者,您可以成为自己的证书颁发机构。

人们不想从证书颁发机构获得签名证书的主要原因是成本--赛门铁克每年收取995美元至1999美元的证书费用--仅针对用于内部网络的证书,赛门铁克每年收取399美元。如果您正在处理信用卡付款或为高利润公司的利润中心工作,那么该成本很容易被证明是合理的。对于一个在互联网上创建的个人项目,或者一个以最低预算运行的非营利组织,或者如果一个人在一个组织的成本中心工作,成本中心总是试图用更少的钱做更多的事情,这是很多人都无法承受的。

另一种方法是使用certbot(参见certbot)。Certbot是一个易于使用的自动客户端,可为web服务器获取和部署SSL/TLS证书。

如果您设置了certbot,则可以使其为您创建和维护Let's Encrypt证书颁发机构颁发的证书。

我在周末为我的组织做了这件事。我在服务器(Ubuntu 16.04)上安装了certbot所需的软件包,然后运行了设置和启用certbot所必需的命令。一个可能需要certbot的DNS插件-我们目前正在使用DigitalOcean,但可能很快会迁移到另一个服务。

请注意,有些指示不太正确,需要谷歌花点时间才能弄清楚。这第一次花了我相当多的时间,但现在我想我可以在几分钟内完成。

对于DigitalOcean,我遇到的一个问题是,系统提示我输入DigitalOcean凭据INI文件的路径。脚本所指的是应用程序和API页面以及该页面上的令牌/密钥选项卡。您需要为DigitalOcean的API创建或生成个人访问令牌(读写)——这是一个65个字符的十六进制字符串。然后需要将该字符串放入运行certbot的Web服务器上的文件中。该文件的第一行可以是注释(注释以#开头)。第二行是:

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

一旦我知道了如何为DigitalOcean的API设置读写令牌,就可以很容易地使用certbot来设置通配符证书。请注意,您不必设置通配符证书,而是可以指定要应用证书的每个域和子域。正是通配符证书需要包含来自DigitalOcean的个人访问令牌的凭据INI文件。

请注意,公钥证书(也称为身份证书或SSL证书)过期并需要续订。因此,您需要定期(重复)更新证书。certbot文档包括续订证书。

我的计划是编写一个脚本,使用openssl命令获取证书的到期日期,并在到期前30天或更短的时间内触发续订。然后我将把这个脚本添加到cron中,并每天运行一次。

以下是读取证书过期日期的命令:

root@prod-host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT

一个内衬FTW。我喜欢保持简单。为什么不使用一个包含所有所需参数的命令?这就是我喜欢的方式-这将创建一个x509证书及其PEM密钥:

openssl req -x509 \
 -nodes -days 365 -newkey rsa:4096 \
 -keyout self.key.pem \
 -out self-x509.crt \
 -subj "/C=US/ST=WA/L=Seattle/CN=example.com/emailAddress=someEmail@gmail.com"

该命令包含通常为证书详细信息提供的所有答案。通过这种方式,您可以设置参数并运行命令,获取输出,然后喝咖啡。

>>更多信息请点击此处<<

openssl允许通过单个命令(-newkey)生成自签名证书指示生成私钥,-x509指示发出自签名证书而不是签名请求)::

openssl req -x509 -newkey rsa:4096 \
-keyout my.key -passout pass:123456 -out my.crt \
-days 365 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

您可以在单独的步骤中生成私钥和构造自签名证书:

openssl genrsa -out my.key -passout pass:123456 2048

openssl req -x509 \
-key my.key -passin pass:123456 -out my.csr \
-days 3650 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

查看生成的证书:

openssl x509 -text -noout -in my.crt

Java keytool创建PKCS#12存储::

keytool -genkeypair -keystore my.p12 -alias master \
-storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \
-storepass 123456 \
-dname "CN=localhost,O=home,C=US" \
-ext 'san=dns:localhost,dns:web.internal,email:me@mail.internal'

要导出自签名证书,请执行以下操作:

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456

查看生成的证书:

keytool -printcert -file my.crt

GnuTLS的certtool不允许从CLI传递不同的属性。我不喜欢乱搞配置文件((

我不能评论,所以我补充了一个单独的答案。我试图为NGINX创建一个自签名证书,这很简单,但当我想将其添加到Chrome白名单时,我遇到了一个问题。我的解决方案是创建一个根证书并用它签署一个子证书。

所以一步一步。创建文件config_ssl_c.cnf注意,配置文件有一个选项basicConstraints=CA:true,这意味着该证书应该是根证书。

这是一个很好的做法,因为您只需创建一次即可重复使用。

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=root region
localityName=root city
organizationName=Market(localhost)
organizationalUnitName=roote department
commonName=market.localhost
emailAddress=root_email@root.localhost

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:true
subjectKeyIdentifier = hash
subjectAltName = @alternate_names

子证书的下一个配置文件将调用config_ssl.cnf。

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=Kyiv region
localityName=Kyiv
organizationName=market place
organizationalUnitName=market place department
commonName=market.localhost
emailAddress=email@market.localhost

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:false
subjectAltName = @alternate_names
subjectKeyIdentifier = hash

第一步-创建根密钥和证书

openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf

第二步创建子密钥和文件CSR-证书签名请求。因为这样做的目的是通过root签名子证书并获得正确的证书

openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr

打开Linux终端并执行以下命令

echo 00 > ca.srl
touch index.txt

ca.srl文本文件包含下一个要使用的十六进制序列号。强制性的此文件必须存在并包含有效的序列号。

最后一步,再创建一个配置文件,并将其命名为config_ca.cnf

# we use 'ca' as the default section because we're usign the ca command
[ ca ]
default_ca = my_ca

[ my_ca ]
#  a text file containing the next serial number to use in hex. Mandatory.
#  This file must be present and contain a valid serial number.
serial = ./ca.srl

# the text database file to use. Mandatory. This file must be present though
# initially it will be empty.
database = ./index.txt

# specifies the directory where new certificates will be placed. Mandatory.
new_certs_dir = ./

# the file containing the CA certificate. Mandatory
certificate = ./ca.crt

# the file contaning the CA private key. Mandatory
private_key = ./ca.key

# the message digest algorithm. Remember to not use MD5
default_md = sha256

# for how many days will the signed certificate be valid
default_days = 365

# a section with a set of variables corresponding to DN fields
policy = my_policy

# MOST IMPORTANT PART OF THIS CONFIG
copy_extensions = copy

[ my_policy ]
# if the value is "match" then the field value must match the same field in the
# CA certificate. If the value is "supplied" then it must be present.
# Optional means it may be present. Any fields not mentioned are silently
# deleted.
countryName = match
stateOrProvinceName = supplied
organizationName = supplied
commonName = market.localhost
organizationalUnitName = optional
commonName = supplied

您可能会问,为什么这么难,为什么我们必须再创建一个配置来按根签名子证书。答案很简单,因为子证书必须具有SAN块-主题替代名称。如果我们使用“openssl x509”utils对子证书进行签名,则根证书将删除子证书中的SAN字段。因此,我们使用“opensslca”而不是“opensslx509”来避免删除SAN字段。我们创建一个新的配置文件,并告诉它复制所有扩展字段copy_extensions=copy。

openssl ca -config config_ca.cnf -out market.crt -in market.csr

该程序会问您两个问题:

签署证书?说“Y”1个证书请求中有1个已认证,是否提交?说“Y”

在终端中,您可以看到一个带有单词“Database”的句子,它表示您通过命令“touch”创建的文件index.txt。它将包含由“openssl-ca”util创建的所有证书的所有信息。要检查证书的有效性,请使用:

openssl rsa -in market.key -check

如果您想查看CRT中的内容:

openssl x509 -in market.crt -text -noout

如果您想了解CSR的内部内容:

openssl req -in market.csr -noout -text