我可以在哪里下载受信任的根CA证书,让我们加密?
Suo openssl S_客户端-连接helloworld.letscrypt.org:443-showcerts
开始时间:1493743196
超时:300(秒)
验证返回代码:20(无法获取本地颁发者证书)
根据此页面http://movingpackets.net/2015/03/16/five-essential-openssl-troubleshooting-commands/:
错误:Num=20:无法获取本地颁发者证书
可以通过添加指向包含所有受信任根证书的文件的-Cafile选项来修复此问题,但是从哪里可以获得这些证书呢?
请注意,我真的很想下载这些文件,而不是通过软件包安装它-我需要它们来调试我正在编写的应用程序的证书将会遇到的进一步问题。
有一个指向LetsEncrypt使用的根证书和中间件的链接。
如果您正在考虑更广泛的CACert捆绑包,例如用于广泛的故障排除,我建议您查看Mozilla CA捆绑包
请注意,要让信任链发挥作用,你应该同时拥有根部和中间体。服务器应该为中间商提供服务。
安德烈,里巴马尔-桑塔罗萨:
Helloworld.letsencrypt.org
要解决此问题,您可能应该在S客户端命令行中添加-servername helloworld.letscrypt.org。这使得S客户端的行为更接近浏览器对TLS协商的方式。然后,您将拥有一套非常不同的证书。
正如@ahaw021所说,您可以从信任链下载证书-让我们加密,但大多数人在大多数情况下都不需要这样做,因为他们的操作系统或浏览器CA捆绑包通常已经包含IdenTrust的DST X3根目录,这是我们习惯上链接到的今天颁发的证书的根目录。谢谢@ahaw021和@Schoen。
通过OpenSSL的输出,我可以得到我对X3证书感兴趣:
Openssl S_客户端-连接helloworld.letscrypt.org:443-showcerts
#...
#Issuer=/C=US/O=让我们加密/CN=让我们加密Authority X3
#...
#验证返回码:20(无法获取本地颁发者证书)
然后我下载了一张自己签名的:
然后我可以验证HelloWorld证书:
Openssl S_CLIENT-CONNECT helloworld.letscrypt.org:443-showcerts-Cafile let加密tauthorityx3.pem
#验证返回代码:0(确定)
我还尝试了X签名的证书:
Openssl S_CLIENT-CONNECT helloworld.letscrypt.org:443-showcerts-Cafile let-ENCRYPT-x3-cross-signed.pem
#验证返回代码:0(确定)
然后,我在我的应用程序主机(这里我称之为my.example.com)而不是helloworld.letscrypt.org上尝试了所有命令,正如我所预期的那样,它们总是为相同的测试CAE返回相同的返回代码,因为它们是用相同的证书签名的。
然而,仍然有一些非常奇怪的事情:有了wget,我不能从我的主人下载:
错误:‘my.example.com.com’的证书不受信任。
错误:‘my.example.com’的证书没有已知的颁发者。
如果我添加证书文件,这就“解决”了:
#欢迎使用我的应用程序
但是,要从helloworld.letscrypt.org下载,我不需要证书:
#...
#/正文>
#如果我使用curl而不是wget,也会观察到同样的行为。
现在的问题是:为什么我需要添加--ca-certify以便wget使用我的证书,而不是使用helloworld.letsEncrypt.org?他们不是签在同一条信任链上吗?@Ribamar-Santarosa
仔细审查信任链。有根和中间体。您最初的问题是关于根证书,但中间证书也起着重要作用。
最主要的区别很可能是您不会为Web服务器配置提供中间件。
指定--ca-certify=letscryptauthorityx3.pem可以解决这个问题,因为Wget知道中间
为了您自己的学习,也不要在工具之间来回跳跃
如果你打算使用openssl--对letscrypt参考站点和你的站点都这样做(因为这给了你一个基准),你可以比较它们。
将OpenSSL用于一个函数,然后跳到wget测试,这会造成混乱。
我进行测试的方式
A)针对您的站点运行,让加密参考站点和另一个站点
B)运行SNI和非SNI版本
C)比较结果集,看看有什么不同。
安德烈,还有几个音符
C)在使用OpenSSL进行测试时,我更喜欢在B中手动指定CA包,这样我就不需要依赖操作系统来提供Bunde。示例语法如下。
我配置的服务器需要SNI(这是一件很好测试的事情),所以如果您不指定服务器名,将不会返回证书
使用SNI
图像.png849×297 13.3 KB
无SNI
Image.png708×354 8.85 KB
电子邮件:andrei@ahaw021
好的,现在我明白了:
Openssl S_CLIENT-CONNECT helloworld.letscrypt.org:443-showcerts|grep“BEGIN CERTIFICATE”
#--开始证书--
#--开始证书--
#--开始证书--
Openssl S_客户端-连接my.example.com:443-showcerts|grep“BEGIN CERTIFICATE”
#--开始证书--
因此,我的应用程序没有提供所需的所有证书,这实际上是真的。我不知何故被/etc/letsencrypt/live/scatologies.com/fullchain.pem,这个名字搞糊涂了,我以为它会包含验证主机所需的所有证书,但事实并非如此。
对于Ruby开发人员来说,它基本上是:
服务器=TCPServer.new nil,侦听端口
SslContext=openssl::ssl::SSLConext.new
SslConext.cert=开始openssl::X509::认证。新的File.open(“/etc/letsencrypt/live/my.example.com/fullchain.pem”)救援零结束
SslConext.key=Begin openssl::pkey::rsa。新File.open(“/etc/letsencrypt/live/my.example.com/privkey.pem”)救援零结束
SslConext.Extra_Chain_cert=[“/etc/letsencrypt/live/my.example.com/chain.pem”].map{|Extra_Cert_PEM_FILE|Begin openssl::X509::证书.new File.Open(Extra_Cert_PEM_FILE)修复无效结束}
#注:我做了一些替换之后没有测试这段代码
SslServer=openssl::ssl::SSLServer.new(服务器,sslContext)
循环DO
连接=sslServer.Accept
线程.new{
#在这里,您可以连接.get以接收已为纯文本的数据,直到它返回nil,Connection.Put字符串以使用HTTPS发送字符串
}
结束
在设置了缺少的sslConext.Extra_Chain_cert之后,我可以确保两个证书都得到了服务:
Openssl S_客户端-连接my.example.com:443-showcerts|grep“BEGIN CERTIFICATE”
#--开始证书--
#--开始证书--
并毫无怨言地下载数据:
#欢迎使用我的应用程序
我仍然不知道如何用Ruby设置/强制SNI/如果它被http://ruby-doc.org/stdlib-2.1.2/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html支持的话。
安德烈:非常感谢你快速而深入的回答!
Ribamar,Hi@Ribamar-Santarosa
很高兴知道它起作用了
因此,我的应用程序没有提供所需的所有证书,这实际上是真的。我不知何故被/etc/letsencrypt/live/scatologies.com/fullchain.pem,这个名字搞糊涂了,我以为它会包含验证主机所需的所有证书,但事实并非如此。
Pem正是域证书+中间证书的组合,但是根据您的系统,它可能需要(我认为Ruby确实需要)您将它们分离出来。这方面没有硬性规定,所以这是需要弄清楚的事情之一
安德烈,里巴马尔-桑塔罗萨:
因此,我的应用程序没有提供所需的所有证书,这实际上是真的。我不知何故被/etc/letsencrypt/live/scatologies.com/fullchain.pem,这个名字搞糊涂了,我以为它会包含验证主机所需的所有证书,但事实并非如此。
就是这样!正如@ahaw021所推断的那样,您的SSLContext库显然不愿意从单个文件加载多证书链。但他们都出现在文件里。
我很高兴您的服务现在成功地为整个链条服务。