我正在为嵌入式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上遇到了一些错误:

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

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


当前回答

在经历了大量的尝试和各种解决方案之后,我仍然面临这样一个问题:为localhost颁发自签名证书会给我带来错误

错误证书无效

在扩展细节时,chrome表示:

您现在无法访问localhost,因为网站已发送加密凭据。。。

唯一难看的方式是键入(直接在这个屏幕上,没有看到文本的任何光标):

(在键盘上键入)这是安全的

这让我继续。

直到我找到extendedKeyUsage=serverAuth,clientAuth

TL;博士

openssl genrsa-out localhost.key 2048openssl req-key localhost.key-new-out localhost.csr(单击输入所有内容,然后用localhost或其他FQDN填写通用名称(CN)。将以下内容放入名为v3.ext的文件中(根据需要进行编辑):

subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints       = CA:TRUE
keyUsage               = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign
extendedKeyUsage       = serverAuth, clientAuth
subjectAltName         = DNS:localhost, DNS:localhost.localdomain
issuerAltName          = issuer:copy

openssl x509-req-in localhost.csr-signkey localhost.key-out localhost.pem-days 3650-sha256-extfile v3.ext

瞧!您可以访问网站,展开“高级”,然后单击“转到本地主机(不安全)”。

其他回答

您可以在一个命令中完成此操作:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365

如果您不想用密码保护您的私钥,也可以添加-node(“no DES”的缩写)。否则,它将提示您输入“至少4个字符”的密码。

天数参数(365)可以替换为任何数字以影响到期日期。然后它会提示您输入“国家名称”之类的信息,但您只需按Enter键并接受默认值即可。

添加-sbj'/CN=localhost'以抑制有关证书内容的问题(用所需域替换localhost)。

自签名证书不会通过任何第三方进行验证,除非您以前将其导入浏览器。如果需要更多的安全性,则应使用由证书颁发机构(CA)签名的证书。

2017年一艘班轮:

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.pem \
-new \
-out server.pem \
-subj /CN=localhost \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
    <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
-sha256 \
-days 3650

这也适用于Chrome 57,因为它提供了SAN,而无需另一个配置文件。它取自这里的一个答案。

这将创建一个包含私钥和证书的.pem文件。如果需要,可以将它们移动到单独的.pem。

如果您想使用openssl生成自签名证书,这里有一个我们生成的脚本,可以按原样使用。

#!/bin/bash

subj='//SKIP=skip/C=IN/ST=Country/L=City/O=MyCompany/OU=Technology'
red='\033[31m'        # red
yellow='\033[33m'        # yellow
green='\033[32m'        # green
blue='\033[34m'        # Blue
purple='\033[35m'      # Purple
cyan='\033[36m'        # Cyan
white='\033[37m'       # White


gencerts(){
certname=$1
pkname=$2
alias=$3
$(openssl genrsa -out $pkname'pem.pem' 4096)
$(openssl req -new -sha256 -key $pkname'pem.pem' -out $certname'csr.csr' -subj $subj)
$(openssl x509 -req -sha256 -days 3650 -in $certname'csr.csr' -signkey $pkname'pem.pem' -out $certname'.crt')
$(openssl pkcs12 -export -out $pkname'.p12' -name $alias -inkey $pkname'pem.pem' -in $certname'.crt')
}

verify(){
pkname=$1
keytool -v -list -storetype pkcs12 -keystore $pkname'.p12'
}

echo -e "${purple}WELCOME TO KEY PAIR GENERATOR"
echo -e "${yellow} Please enter the name of the certificate required: "
read certname
echo -e "${green}Please enter the name of the Private Key p12 file required: "
read pkname
echo -e "${cyan}Please enter the ALIAS of the Private Key p12 file : "
read pkalias
echo -e "${white}Please wait while we generate your Key Pair"

gencerts $certname $pkname $pkalias
echo -e "${white}Now lets verify the private key :)"

tput bel     # Play a bell

verify $pkname

请告诉我是否可以对脚本进行任何改进。

生成10年无密码和证书的密钥,短方法:

openssl req  -x509 -nodes -new  -keyout server.key -out server.crt -days 3650 -subj "/C=/ST=/L=/O=/OU=web/CN=www.server.com"

对于标志-subj |,允许使用subject空值-subj“/C=/ST=/L=/O=/OU=web/CN=www.server.com”,但可以根据需要设置更多详细信息:

C-国家名称(2字母代码)ST-状态L-地点名称(如城市)O-组织名称OU-组织单位名称CN-通用名称-必填!

我不能评论,所以我补充了一个单独的答案。我试图为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