如何使用OpenSSL创建自签名证书

mic*_*con 1169 ssl openssl certificate ssl-certificate x509certificate

我正在为嵌入式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
Run Code Online (Sandbox Code Playgroud)

这有效,但我在使用Google Chrome时遇到了一些错误:

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

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

Die*_*sen 1946

您可以在一个命令中执行此操作:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Run Code Online (Sandbox Code Playgroud)

如果您不想使用密码短语保护私钥,也可以添加-nodes(缩写no DES).否则它会提示您输入"至少4个字符"的密码.

days你可以用任何数量的替代参数(365)影响的到期日期.然后它会提示您输入"国家/地区名称"等内容,但您可以点击Enter并接受默认值.

添加-subj '/CN=localhost'以禁止有关证书内容的问题(替换localhost为您所需的域).

除非您先前将自签名证书导入浏览器,否则不会向任何第三方验证自签名证书.如果需要更高的安全性,则应使用由证书颁发机构(CA)签名的证书.

  • 对于在自动化中使用它的任何其他人,这里是该主题的所有常见参数:`-subj"/ C = US/ST = Oregon/L = Portland/O =公司名称/ OU = Org/CN = www.example. COM"` (172认同)
  • 记得使用`-sha256`生成基于SHA-256的证书. (63认同)
  • 与第三方签约如何提供更高的安全性? (14认同)
  • 对于任何有兴趣的人,如果您想自己验证任何内容,请参阅[文档](https://www.openssl.org/docs/apps/req.html). (6认同)
  • @Rob - IETF和CA/B论坛都不推荐在CN中放置DNS名称(如localhost).虽然它被弃用了,但它目前还没有被禁止(CA/B接下来会出现这种情况).所有名称都以主题备用名称出现.如果证书在CN中具有DNS名称,则它也必须存在于SAN中.否则,证书将无法在遵循CA/B的浏览器和其他用户代理下进行验证.没有办法避免使用SAN. (5认同)
  • @JamesMills我的意思是,想一想 - 如果一个看起来很阴沉的男人在他的面包车上写着"免费糖果"邀请你进来,你会完全三思而后悔 - 但是如果你信任的人 - 比如*真的*信任 - 就像是,"呐喊男人,他是合法的",你将成为那个免费糖果的全部. (5认同)
  • @JamesMills 我看到的只是你的问题,没有看到其他任何内容。-- 详细说明:基本上它可以防止冒充攻击(即中间人等) -- 更多信息:https://en.wikipedia.org/wiki/Man-in-the-middle_attack (3认同)
  • 对所有提议的改进都被忽略感到失望,我创建了一个新答案,其中包含了评论的所有改进:http://stackoverflow.com/a/41366949/19163 (3认同)
  • 这支持通配符吗? (2认同)
  • 是的,但因为是一个自签名的证书,通常没有任何意义:) (2认同)
  • @diegows - 谢谢你的回答.我继续谷歌搜索它,因为我*从来没有*记住它是'req'子命令的一部分,而不是'x509'子命令.即使我这样做了,我也要抓挠我的头,尝试几次才能做到正确.谢谢你让我的一天变得更顺畅. (2认同)
  • 很好的答案,除了 CA 签名增加了更多安全性的赞扬。最好的安全性是依赖于您以安全方式(例如面对面)交换的公钥。PKIX、CA 签名等使其可扩展到小型社区之外,但实际上引入了新的攻击向量。 (2认同)

jww*_*jww 495

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

创建自签名证书很容易.你只需使用该openssl req命令.创建一个可供最大客户端选择的服务器(如浏览器和命令行工具)可能会很棘手.

这很困难,因为浏览器有自己的一套要求,而且它们比IETF更具限制性.浏览器使用的要求记录在CA /浏览器论坛中(请参阅下面的参考资料).这些限制出现在两个关键领域:(1)信任锚,以及(2)DNS名称.

现代浏览器(如我们在2014/2015年使用的warez)需要一个链接回信任锚的证书,并且他们希望在证书中以特定方式呈现DNS名称.浏览器正在积极地反对自签名服务器证书.

某些浏览器并不能完全轻松导入自签名服务器证书.事实上,你不能用某些浏览器,比如Android的浏览器.所以完整的解决方案就是成为你自己的权威.

如果没有成为您自己的权限,您必须获得正确的DNS名称,以便为证书提供最大的成功机会.但我鼓励你成为自己的权威.很容易成为你自己的权威,它会回避所有的信任问题(谁比你自己更信任?).


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

这是因为浏览器使用预定义的信任锚列表来验证服务器证书.自签名证书不会链回到受信任的锚点.

避免这种情况的最佳方法是:

  1. 创建自己的权限(即成为CA)
  2. 为服务器创建证书签名请求(CSR)
  3. 使用CA密钥对服务器的CSR进行签名
  4. 在服务器上安装服务器证书
  5. 在客户端上安装CA证书

步骤1 - 创建自己的权限只是意味着创建一个具有CA: true正确密钥用法的自签名证书.这意味着SubjectIssuer是同一个实体,CA在Basic Constraints中设置为true (它也应该被标记为关键),密钥用法是keyCertSigncrlSign(如果您使用的是CRL),主题密钥标识符(SKI)是与权威密钥标识符(AKI)相同.

要成为您自己的证书颁发机构,请参阅*如何使用您的证书颁发机构签署证书签名请求?在Stack Overflow上.然后,将您的CA导入浏览器使用的Trust Store.

当您获得CA(如StartcomCAcert)的服务时,步骤2 - 4大致就是面向公共服务器的操作.步骤1和5允许您避免第三方权限,并充当您自己的权限(谁比您自己更信任?).

避免浏览器警告的下一个最佳方法是信任服务器的证书.但有些浏览器,比如Android的默认浏览器,不允许你这样做.所以它永远不会在平台上运行.

信任自签名证书的浏览器(和其他类似用户代理)的问题将成为物联网(IoT)中的一个大问题.例如,当您连接到恒温器或冰箱进行编程时会发生什么?答案是,就用户体验而言,没什么好处.

W3C的WebAppSec工作组正在开始研究这个问题.例如,请参阅提案:将HTTP标记为不安全.


如何使用OpenSSL创建自签名证书

以下命令和配置文件创建自签名证书(它还向您显示如何创建签名请求).它们在一个方面与其他答案不同:用于自签名证书的DNS名称位于主题备用名称(SAN)中,而不是公用名称(CN).

DNS名称通过带有该行的配置文件放置在SAN中subjectAltName = @alternate_names(无法通过命令行执行此操作).然后alternate_names在配置文件中有一个部分(你应该调整它以适合你的口味):

[ 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
Run Code Online (Sandbox Code Playgroud)

把DNS名称的SAN,而不是在CN,因为它是重要的两个 IETF和CA /浏览器论坛指定的做法.它们还指定不推荐使用CN中的DNS名称(但不禁止).如果在CN中放置DNS名称,则必须将其包含在CA/B策略下的SAN中.因此,您无法避免使用主题备用名称.

如果您没有在DNS中放置DNS名称,则证书将无法在遵循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
Run Code Online (Sandbox Code Playgroud)

创建签名请求(注意缺少-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
Run Code Online (Sandbox Code Playgroud)

打印自签名证书:

openssl x509 -in example-com.cert.pem -text -noout
Run Code Online (Sandbox Code Playgroud)

打印签名请求:

openssl req -in example-com.req.pem -text -noout
Run Code Online (Sandbox Code Playgroud)

配置文件(通过-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
Run Code Online (Sandbox Code Playgroud)

您可能需要为Chrome执行以下操作.否则Chrome可能会抱怨Common Name无效(ERR_CERT_COMMON_NAME_INVALID).我不确定SAN中的IP地址与此实例中的CN之间的关系.

# IPv4 localhost
# IP.1       = 127.0.0.1

# IPv6 localhost
# IP.2     = ::1
Run Code Online (Sandbox Code Playgroud)

关于在X.509/PKIX证书中处理DNS名称还有其他规则.有关规则,请参阅这些文档:

列出了RFC 6797和RFC 7469,因为它们比其他RFC和CA/B文档更具限制性.RFC 6797和7469 不允许IP地址.

  • @diegows - 你的答案不完整或正确.在你不想阅读的长篇文章中讨论了它不正确的原因:) (14认同)
  • 是否可以在`alternate_names`部分使用通配符?特别是子域.我在这里提到一个引用这个答案的问题:http://serverfault.com/questions/711596/can-i-use-wildcards-with-san-self-signed-certificates (4认同)
  • 谢谢@jww.你说,_"1.创建你自己的权限(即,成为一个CA)"_,然后说,_"5.在客户端安装CA证书"_.如果根密钥被泄露,恶意的人可以为使用该密钥的任何域签署证书,如果他们欺骗您进入他们的网站,他们现在可以进行中间人攻击.有没有办法创建根CA,使其只能签署中间CA而不是证书?然后,您可以使用名称约束来保护您的中间CA. (4认同)
  • 我刚才回答了他的具体问题.我认为当答案如此简单时添加这个长安全性描述是没有意义的 (2认同)

小智 398

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

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
Run Code Online (Sandbox Code Playgroud)
req
Run Code Online (Sandbox Code Playgroud)

PKCS#10证书请求和证书生成实用程序.

-x509
Run Code Online (Sandbox Code Playgroud)

此选项输出自签名证书而不是证书请求.这通常用于生成测试证书或自签名根CA.

-newkey arg
Run Code Online (Sandbox Code Playgroud)

此选项可创建新证书请求和新私钥.该论证采用了几种形式之一.rsa:nbits,其中nbits是位数,生成大小为nbits的RSA密钥.

-keyout filename
Run Code Online (Sandbox Code Playgroud)

这给出了将新创建的私钥写入的文件名.

-out filename
Run Code Online (Sandbox Code Playgroud)

这默认指定要写入的输出文件名或标准输出.

-days n
Run Code Online (Sandbox Code Playgroud)

当使用-x509选项时,它指定证书证书的天数.默认值为30天.

-nodes
Run Code Online (Sandbox Code Playgroud)

如果指定了此选项,则如果创建了私钥,则不会对其进行加密.

文档实际上比上面更详细; 我只是在这里总结一下.

  • 原始命令中的"XXX"应替换为"证明证书的天数".默认值为30天.例如,如果您希望您的证书有效期为365天,`-days XXX`将成为`-days 365`.[请参阅文档了解更多信息](https://www.openssl.org/docs/manmaster/apps/req.html). (3认同)

vog*_*vog 250

自2019年起,以下命令可满足您的所有需求,包括SAN:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1
    ) \
  -subj /CN=example.com
Run Code Online (Sandbox Code Playgroud)

在OpenSSL≥1.1.1中,这可以缩短为:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -subj /CN=example.com \
  -addext subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1
Run Code Online (Sandbox Code Playgroud)

它创建了一个证书

  • 对域example.comexample.net(SAN)有效,
  • 也适用于IP地址10.0.0.1(SAN),
  • 相对较强(截至2019年)和
  • 有效期为3650几天(〜10年).

它会创建以下文件:

  • 私钥: example.key
  • 证书: example.crt

所有信息都在命令行中提供.没有讨厌的交互式输入.配置文件没有搞乱.所有必要的步骤都由这个单一的OpenSSL调用执行:从私钥生成到自签名证书.

备注#1:加密参数

由于证书是自签名的并且需要手动接受用户,因此使用短期过期或弱加密是没有意义的.

在将来,您可能希望使用比4096RSA密钥更多的位和更强的哈希算法sha256,但是从2019年开始这些是理智的值.它们足够强大,同时得到所有现代浏览器的支持.

备注#2:参数" -nodes"

从理论上讲,您可以省略-nodes参数(这意味着"无DES加密"),在这种情况下example.key将使用密码加密.但是,这几乎不会对服务器安装有用,因为您也必须将密码存储在服务器上,或者您必须在每次重新启动时手动输入密码.

备注#3:MinGW

在MinGW bash的Windows上,您应该在命令前加上MSYS_NO_PATHCONV=1:

MSYS_NO_PATHCONV=1 openssl ...
Run Code Online (Sandbox Code Playgroud)

或者,在cmd.exeWindows Windows命令提示符下运行该命令.

备注#4:另见

  • 1000 +1 秒即可创建一个使用新所需 SAN 的“一行”,而无需创建包含大量样板文件的冗长配置文件。做得好! (19认同)
  • 如果您在 Windows 上使用 git bash,例如 @YuriyPozniak,您将收到他列出的错误,其中“/CN=localhost”正在扩展为“C:/Progra Files/Git/CN=localhost”。如果添加额外的 /,则不会发生扩展。`//CN=本地主机` (7认同)
  • 我尝试在 mingw64 的 windows 上使用 oneliner #2(现代),但我遇到了一个带有 -subj 参数的错误。` $ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout localhost.key -out localhost.crt -subj '/CN=localhost' -addext subjectAltName=DNS:localhost,IP:127.0.0.1 生成RSA 私钥 [...] 将新的私钥写入 'localhost.key' ----- 名称的格式应为 /type0=value0/type1=value1/type2=... 其中字符可能为被\转义。此名称不是那种格式:'C:/Program Files/Git/CN=localhost' 产生证书请求的问题` (2认同)
  • 我无法弄清楚在扩展到 C:/Program Files/Git/CN=localhost 的 arg /CN=localhost 中究竟应该归咎于什么,所以我只是在普通的 cmd.exe 中运行了整个命令,它工作得很好。以防万一有人在这个问题上挣扎。 (2认同)
  • @FranklinYu 你确定 rsa:2048 在 10 年后就足够了吗?因为那是有效期。正如所解释的,使用短期到期或弱加密是没有意义的。大多数2048位RSA密钥的有效期最多为1-3年。关于 OpenSSL 1.1.1,我仍然将 sha256 保留在那里,因此如果您想要更强的哈希值,更改会更加明确和明显。 (2认同)
  • 截至 2020 年 8 月 31 日,我可以保证这是有效的!!!多谢!我真的很希望看到一份参考资料,能够用简单的语言解释为什么它会以如此快的速度发展。我有些想知道这是否只是因为创建自签名证书的想法对大型科技公司来说适得其反。10年或20年后需要什么?这太疯狂了,这证明了 openssl 上此类问题产生的活动量。 (2认同)

Mik*_*e N 132

我无法发表评论,所以我将此作为一个单独的答案.我发现了一些被接受的单行答案的问题:

  • 单行包含密钥中的密码.
  • 单行使用SHA-1,在许多浏览器中都会在控制台中发出警告.

这是一个简化版本,用于删除密码,提升安全性以抑制警告,并在注释中包含一个建议,以传入-subj以删除完整的问题列表:

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
Run Code Online (Sandbox Code Playgroud)

将"localhost"替换为您需要的任何域.您将需要逐个运行前两个命令,因为OpenSSL将提示输入密码.

要将两者合并为.pem文件:

cat server.crt server.key > cert.pem
Run Code Online (Sandbox Code Playgroud)

  • 我需要https://github.com/molnarg/node-http2的开发证书,这个答案是最好的. (6认同)
  • key.pem文件怎么样? (2认同)

rym*_*ymo 73

如果缺少SAN(主题备用名称),现代浏览器现在会为其他格式良好的自签名证书抛出安全性错误.OpenSSL没有提供命令行方式来指定它,因此许多开发人员的教程和书签突然过时了.

再次运行的最快方法是一个简短的独立conf文件:

  1. 创建一个OpenSSL的配置文件(例如:req.cnf)

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建引用此配置文件的证书

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    
    Run Code Online (Sandbox Code Playgroud)

示例配置来自https://support.citrix.com/article/CTX135602

  • 您现在可以在命令行上使用`-extension'ajectAltName = DNS:dom.ain,DNS:oth.er'指定SAN.请参阅https://github.com/openssl/openssl/pull/4986 (5认同)
  • 扎实的方式.谢谢.我建议添加`-sha256`. (2认同)
  • 看起来此选项现在称为`-addext`。 (2认同)

Mar*_* B. 65

我建议添加-sha256参数,以使用SHA-2哈希算法,因为主流浏览器正在考虑将"SHA-1证书"显示为不安全.

接受的答案中的命令行相同 - @diegows添加了-sha256

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

Google安全博客中的更多信息.

更新于2018年5月.正如评论中所指出的那样,使用SHA-2不会为自签名证书添加任何安全性.但我仍然建议使用它作为不使用过时/不安全的加密哈希函数的好习惯.为什么对于基于SHA-1的终端实体证书以上的证书,可以使用完整的解释.

  • @Mark,这很重要,因为SHA-2更安全 (29认同)
  • 请注意,自签名证书上使用的签名算法在决定它是否值得信任时无关紧要.根CA证书是自签名的.截至2018年5月,仍有许多SHA-1签名的活动根CA证书.因为证书是否信任自身无关紧要,也不知道该证书如何验证该信任.您要么信任根/自签名证书,要么*它说它是谁,要么你不相信.请参阅https://security.stackexchange.com/questions/91913/why-is-it-fine-for-certificates-above-the-end-entity-certificate-to-be-sha1-base (4认同)
  • 如果它是自签名密钥,无论如何它都会生成浏览器错误,所以这并不重要 (2认同)
  • "世界级加密*零认证=零安全"http://www.gerv.net/security/self-signed-certs/ (2认同)

Dra*_*kes 19

这是我在本地框中使用的脚本,用于在自签名证书中设置SAN(subjectAltName).

此脚本使用域名(example.com)并在同一证书中为*.example.com和example.com生成SAN.以下部分进行了评论.命名脚本(例如generate-ssl.sh)并赋予其可执行权限.这些文件将写入与脚本相同的目录中.

Chrome 58以后需要在自签名证书中设置SAN.

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"
Run Code Online (Sandbox Code Playgroud)

此脚本还会写入信息文件,因此您可以检查新证书并验证SAN是否已正确设置.

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Apache,那么您可以在配置文件中引用上述证书,如下所示:

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

请记住重新启动Apache(或Nginx或IIS)服务器以使新证书生效.


小智 14

我无法发表评论,所以我添加了一个单独的答案。我尝试为 NGINX 创建一个自签名证书,这很容易,但是当我想将它添加到 Chrome 白名单时,我遇到了问题。我的解决方案是创建一个根证书并由它签署一个子证书。

所以一步一步来。创建文件config_ssl_ca.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
Run Code Online (Sandbox Code Playgroud)

子证书的下一个配置文件将调用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
Run Code Online (Sandbox Code Playgroud)

第一步——创建Root密钥和证书

openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf
Run Code Online (Sandbox Code Playgroud)

第二步创建子密钥和文件 CSR - 证书签名请求。因为思路是通过root对子证书进行签名,得到正确的证书

openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr
Run Code Online (Sandbox Code Playgroud)

打开 Linux 终端并执行此命令

echo 00 > ca.srl
touch index.txt
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

openssl ca -config config_ca.cnf -out market.crt -in market.csr
Run Code Online (Sandbox Code Playgroud)

该程序会问您两个问题:

  1. 签署证书?说“Y”
  2. 1 个证书请求中的 1 个获得认证,提交?说“Y”

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

openssl rsa -in market.key -check
Run Code Online (Sandbox Code Playgroud)

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

openssl x509 -in market.crt -text -noout
Run Code Online (Sandbox Code Playgroud)

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

openssl req -in market.csr -noout -text 
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个过程看起来很复杂,但这正是我们对 .dev 域所需要的,因为该域不支持自签名证书,并且 Chrome 和 Firefox 强制使用 HSTS。我所做的是遵循以下步骤,即创建 CA、创建证书并使用我的 CA 对其进行签名,最后在浏览器中信任我的 CA。谢谢。 (2认同)

Mao*_*dok 10

生成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"
Run Code Online (Sandbox Code Playgroud)

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

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


joe*_*rvi 9

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
Run Code Online (Sandbox Code Playgroud)

这也适用于Chrome 57,因为它提供了SAN,而没有其他配置文件.它取自这里的答案.

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

  • 对于Linux用户,您需要更改配置的路径.例如,在当前的Ubuntu`/etc/ssl/openssl.conf`上工作 (2认同)

gav*_*koa 9

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
Run Code Online (Sandbox Code Playgroud)

您可以通过单独的步骤生成私钥并构建自签名证书:

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
Run Code Online (Sandbox Code Playgroud)

查看生成的证书::

openssl x509 -text -noout -in my.crt
Run Code Online (Sandbox Code Playgroud)

Javakeytool创建 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'
Run Code Online (Sandbox Code Playgroud)

导出自签名证书:

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456
Run Code Online (Sandbox Code Playgroud)

查看生成的证书::

keytool -printcert -file my.crt
Run Code Online (Sandbox Code Playgroud)

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


use*_*843 8

2017年单线版:

CentOS:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))
Run Code Online (Sandbox Code Playgroud)

Ubuntu:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "/CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))
Run Code Online (Sandbox Code Playgroud)

编辑:在 Ubuntu 的“subj”选项前添加斜杠。


nne*_*eko 6

您的一般程序是正确的.该命令的语法如下.

openssl req -new -key {private key file} -out {output file}
Run Code Online (Sandbox Code Playgroud)

但是,会显示警告,因为浏览器无法通过使用已知证书颁发机构(CA)验证证书来验证身份.

由于这是一个自签名证书,因此没有CA,您可以放心地忽略该警告并继续.如果您想获得公共互联网上任何人都能识别的真实证书,那么程序如下.

  1. 生成私钥
  2. 使用该私钥创建CSR文件
  3. 向CA提交CSR(Verisign或其他人等)
  4. 在Web服务器上从CA安装收到的证书
  5. 根据类型证书将其他证书添加到身份验证链

我在安全连接:使用OpenSSL创建安全证书的帖子中有关于此的更多详细信息


Oke*_*ieE 6

一个班轮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"
Run Code Online (Sandbox Code Playgroud)

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

>>更多这里<<


Ric*_*ard 6

快速命令行:最小版本

“我想要一个 pfx 形式的自签名证书,用于www.example.com ,无需大惊小怪”:

openssl req -x509 -sha256 -days 365 -nodes -out cert.crt -keyout cert.key -subj "/CN=www.example.com"
openssl pkcs12 -export -out cert.pfx -inkey cert.key -in cert.crt
Run Code Online (Sandbox Code Playgroud)


Tho*_*ner 5

生成密钥

/etc/mysql用于证书存储,因为/etc/apparmor.d/usr.sbin.mysqld包含/etc/mysql/*.pem r.

sudo su -
cd /etc/mysql
openssl genrsa -out ca-key.pem 2048;
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem;
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem;
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;
Run Code Online (Sandbox Code Playgroud)

添加配置

/etc/mysql/my.cnf

[client]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[mysqld]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem
Run Code Online (Sandbox Code Playgroud)

在我的设置中,Ubuntu 服务器登录到: /var/log/mysql/error.log

后续注意事项:


备用链接:使用 SSL 将 PHP 连接到 MySQL 中的冗长教程。


Pet*_*tch 5

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

\n\n

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

\n\n

另一种方法是使用certbot(请参阅有关 certbot 的信息)。Certbot 是一个易于使用的自动客户端,可为您的 Web 服务器获取和部署 SSL/TLS 证书。

\n\n

如果您设置 certbot,则可以让它为您创建和维护由Let\xe2\x80\x99s Encrypt证书颁发机构颁发的证书。

\n\n

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

\n\n

请注意,有些说明不太正确,需要在 Google 上进行一些探索和时间才能弄清楚。第一次这花了我相当多的时间,但现在我想我可以在几分钟内完成。

\n\n

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

\n\n
dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff\n
Run Code Online (Sandbox Code Playgroud)\n\n

一旦我弄清楚如何为 DigitalOcean 的 API 设置读+写令牌,使用 certbot 设置通配符证书就变得非常容易。请注意,不必设置通配符证书,而是可以指定想要应用证书的每个域和子域。通配符证书需要包含来自 DigitalOcean 的个人访问令牌的凭据 INI 文件。

\n\n

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

\n\n

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

\n\n

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

\n\n
root@prod-host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file\nnotAfter=May 25 19:24:12 2019 GMT\n
Run Code Online (Sandbox Code Playgroud)\n


归档时间:

查看次数:

1394872 次

最近记录:

5 年,11 月 前