当我尝试在https://git.ffmpeg.org/ffmpeg.git从LiClipse交互到受SSL保护的git repo时,我得到一个对话,内容如下:
为https://git.ffmpeg.org/ffmpeg.git提供信息
无法建立与https://git.ffmpeg.org/ffmpeg.git的安全连接,因为无法验证服务器的证书。
SSL报告:PKIX路径构建失败:sun.security. Provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径
是否要跳过此服务器的SSL验证?
跳过SSL验证这个单一的git操作[]
跳过SSL验证存储库 /my/workspace/ffmpeg/.git的git操作[]
从现在开始,始终跳过此服务器的SSL验证[]
[Cancel] [OK]
所以,我知道LiClipse正在使用Eclipse插件EGit来处理git拉取请求,并且EGit正在通过安装的Java机器来满足请求。我不清楚EGit是使用作为Eclipse的一部分安装的Java机器,还是安装在主机OS上的Java机器。我知道是否有一个目录或其他位置,我在其中放置了从主机检索的SSL证书文件(https://git.ffmpeg.org/)。
证书的位置在哪里?如何根据LiClipse或Eclipse安装的内容以及主机OS上的Java实用程序确定证书?
如何从git服务器中检索适当的证书?可能使用我的浏览器,或者我传递URL或域名的命令行实用程序,但是什么?证书很可能是自签名的,这对事情有什么影响?
如何将从服务器检索的证书转换为LiClipse或Eclipse可以使用的形式?我是否运行了一些Java证书实用程序?
如何将转换后的证书安装到正确的位置?
我不熟悉JavaSSL和证书处理的行话和结构,所以请解释首字母缩略词和/或指出适当的概述留档。
我正在使用LiClipse4.3.1.201711062215,基于Eclipse Platform 4.7.1. v20170906-1700,在MacOSX El Capitan 10.11.6上。
这里有一些相关的页面,它们可能给出了部分答案,但假设我没有Java体系结构的知识,或者适用于其他不是Eclipse、Egit和LiClipse的基于Java的系统。
从这个问题的问号数量可以看出,这是一种需要将几条知识连接在一起才能形成答案的情况。单个部分都不难,尽管有些(LiClipse)很模糊,有些(Java的keytools)在留档中回答,不容易找到。
首先解释一下。Eclipse主要是Java语言代码,它运行在JRE(Java运行时环境)上。“SSL”指的是通信协议。后来它被重命名为“TLS”,但我在这里将使用“SSL”。事实证明,通信SSL由JRE处理:“PKIX”指的是一个工作组,它提出了SSL使用的证书系统,“sun.security. Provider
”表示JavaSE安全体系结构正在处理通信。
SSL安全性的一部分是验证,当你要求连接到某个互联网站点时,比如“git.ffmpeg.org”,你真的到达了那个站点,而不是冒名顶替者。“证书”是一小块数据,它识别一个目的地名称,并通过颁发该证书的服务的数字签名来证明该数据的正确性。如果你信任颁发者,并且证书上的签名是有效的,你就可以信任生成的证书所说的话。颁发服务本身有一个证书,由它自己的颁发服务依次签名。证书以“信任链”链接到它们的颁发者。一些证书和一些颁发者锚定了这条链。这被称为“根证书”。
JRE在JRE信任库中包含多个根证书的副本。它存储在JRE的JavaHome目录中的一个文件中,位于./lib/security/cacerts
)。JRE还包括一个工具./bin/keytools
,它可以从信任库中添加和删除证书。但是JRE并不包括每个重要的根证书。
该错误对话框告诉我们的是,LiClipse和EGit要求JRE的安全代码将信任链中的证书连接起来,从git.ffmpeg.org服务器的证书,到JRE信任存储中的某个证书。这失败了,因为信任存储缺少必要的证书。解决方案是将git.ffmpeg.org的证书添加到本地JRE信任存储中。JRE的keytools
将允许我们添加它。(如果您相信服务器根证书背后的人只有良好参与者的经过身份验证的证书,您可以改为添加以服务器证书结尾的信任链中的根证书。如果你的风险很高,在信任之前,你可能应该得到一个比这篇博客文章更好的安全简报。)
所以,我们需要做的是:
首先,我们获取目标服务器git.ffmpeg.org的SSL证书。或者,我们可以从服务器证书的信任链中获取根“证书授权中心”(CA)证书。如果您获得了服务器的证书,则仅将该服务器标记为受信任的。如果您获得了CA根证书,则可以使用任何具有该CA直接或间接颁发的证书的服务器,这可能是更多的服务器。然而,也许您并不信任每个CA所做的一切。做出这种权衡超出了这些说明的范围。
获取目标服务器SSL证书的直接方法是通过OpenSSL命令行工具。
% openssl s_client -connect git.ffmpeg.org:443 </dev/null 2>/dev/null >cert.crt
(详情:openssls_client是一个SSL/TLS协议客户端的参考实现,它正确地与服务器通信,有助于诊断。s_client从标准输入读取HTTP命令,所以"
这将目标服务器的证书存储在文件cert. crt
中。它的大小约为2182字节左右。它看起来像这样:
-----BEGIN CERTIFICATE-----
MIIGBDCCBOygAwIBAgISA/dw6A9zk496P+FouEc0W3OyMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
... [ 29 lines omitted ] ...
7U4xF6Csg3X76Xx35kIVO/JJOhoDbGIydD1Cya7dba9ZhNFa+KU1uiyu5AX+i4fd
bCXI4Ukqzwc=
-----END CERTIFICATE-----
或者,您可以使用Firefox Web浏览器(v57左右)下载目标服务器的证书。导航到https://git.ffmpeg.org。按照Mozilla的说明查看站点的证书。
在Chrome和Safari,似乎无法下载证书本身,但您可以获得一个带有证书信息的文本文件,可读但不可重用。
根CA证书更难获得。openssls_client
的-showcerts
选项将打印出信任链。与留档的说法相反,这只是服务器发送的证书。服务器通常不会在其信任链的根发送根CA证书。(参见OpenSSL问题s_client-showcerts man文本误导:“链中的所有证书”,#4933。)但是,此选项确实打印出根CA证书上的名称。它是服务器发送的最终证书的颁发者。
% openssl s_client -connect git.ffmpeg.org:443 -showcerts </dev/null 2>/dev/null
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=ffmpeg.org
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----
MIIGBDCCBOygAwIBAgISAzCih69KsBB6DxJc3koSpgrMMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
... [ 29 lines omitted ] ...
Gi010DGiJpnEM3LIcrsokySWppACKkBCcEW3dlAL/kX+8CQrtT+ns8OtAC2RYuMF
jGjs0Nphih0=
-----END CERTIFICATE-----
1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
... [ 29 lines omitted ] ...
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----
---
根CA证书标识为:/O=Digital Signature Trust Co./CN=DST根CAX3
。
有几个地方可以查找根CA证书的集合。每个浏览器都包含它信任的证书的集合,并且可以找到包含该集合的文件。但我找到的最简单的来源是MacPorts与openssl一起安装的证书。这些证书位于OpenSSL数据位置,该位置被编译为OpenSSL的目录。查找名为cert. pem的文件和名为cert/的目录(有关更多信息,请参阅Paul Heinlein的OpenSSL识别哪些证书颁发机构?)在我的计算机上,它看起来像:
% openssl version -d OPENSSLDIR: "/opt/local/etc/openssl"
要列出OpenSSL信任的所有证书文件的路径,您可以使用此命令。(来源:我对如何列出证书的回答,受OpenSSL信任?在StackOverflow上。)
% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \
-type f -exec ls -l {} \+
lrwxr-xr-x 1 root admin 40 29 Nov 02:05 /opt/local/etc/openssl/cert.pem -> /opt/local/share/curl/curl-ca-bundle.crt
(如果你想对证书文件做一些不同的事情,你可以使用不同的命令来代替上面的“ls-l{}
”。)所以,这表明我的OpenSSL安装重用了工具“cUrl”中的curl-ca-bundle. crt
。)查看该文件,我看到它用我在服务器证书的/CN字段中看到的相同名称标记每个证书。此命令使用grep来查找和打印该证书。您可以省略-text选项以在开始时忽略文本版本:
% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \
-type f -exec grep -B 1 -A 19 'DST Root CA X3' {} \+ | openssl x509 -text
Certificate:
... [ 4 lines omitted ] ...
Signature Algorithm: sha1WithRSAEncryption
Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3
Validity
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Subject Public Key Info:
... [ 45 lines omitted ] ...
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
... [ 11 lines omitted ] ...
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
从"--BEGIN CERTIFICATE--
"行到"--END CERTIFICATE--
"行的证书文本是您可以选择安装在LiClipse中的根CA证书。要将该部分放入文件中,请从上述命令中删除-text
选项,并将结果通过管道传输到名称为"DSTRootCAX3. crt
"的文件中。
证书安装在LiClipse使用的Java运行时环境(JRE)中。下一个任务是识别这个JRE及其JavaHome目录的位置。
幸运的是,LiClipse(for Mac)是否包含自己的JRE副本?这个问题在Stack Overflow上得到了回答。是的,LiClipse for Mac确实包含自己的JRE。JavaHome目录位于应用程序包中的./jre/Contents/Home
。./bin
子目录具有可执行文件,如主java可执行文件。
% cd /Applications/LiClipse\ 4.0.0/LiClipse.app/jre/Contents/Home
% ls -F
COPYRIGHT THIRDPARTYLICENSEREADME.txt man/
LICENSE Welcome.html release
README bin/
THIRDPARTYLICENSEREADME-JAVAFX.txt* lib/
% bin/java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
JREJava包括一个命令行实用程序keytools,用于管理该JRE的密钥。该实用程序位于JRE中的./bin/keytools
。您可以通过阅读keytools留档来了解更多信息。您还可以使用keytools的-help
选项运行keytools,并阅读keytools手册页(使用“man-M man/
”来获取JRE的手册页,而不是系统的手册页。)而且,虽然许多关于keytools的网页将假设Windows并显示“keytools. exe”,但在Mac上,您当然不使用“.exe”扩展名。
% cd /Applications/LiClipse\ 4.0.0/LiClipse.app/jre/Contents/Home
% man -M man/ keytool
... [man page omitted] ...
% bin/keytool -help
Key and Certificate Management Tool
... [20 lines omitted] ...
Use "keytool -command_name -help" for usage of command_name
这个密钥工具是我们用来将密钥添加到信任存储的工具。
JRE将在不同的位置查找键。默认是~/. keystore
,一个与当前用户绑定的位置,该用户的所有JRE都可以查阅。默认情况下,该位置没有任何内容。回退位置位于JRE的JavaHome目录下,一个文件./lib/security/cacerts
。
这些位置是关于Java安全体系结构的更大故事的一部分,我不会在这里进入。您可以通过阅读keytools留档的术语部分和Java密码体系结构(JCA)参考指南来开始学习它。您将看到术语“密钥存储”,它与“信任存储”相关。有时这些术语可以互换使用。对于我们的目的,“信任存储”是正确的术语。
权宜之计是修改JRE的本地Trust Store。路径如上。keytools留档的cacerts部分告诉我们它的初始密码是“changeit
”。对于LiClipse JRE,这可能仍然是它的密码。
剩下的就是把这些部分放在一起。使用密钥工具将新的服务器SSL证书或根CA证书添加到LiClipse JRE的信任存储中。
% cd /Applications/LiClipse\ 4.0.0/LiClipse.app/jre/Contents/Home
% bin/keytool -import -alias FFmpeg.org -file cert.crt -keystore lib/security/cacerts -storepass changeit
Owner: CN=ffmpeg.org
Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Serial number: 3f770e80f73938f7a3fe168b847345b73b2
Valid from: Tue Oct 31 23:22:03 PDT 2017 until: Mon Jan 29 22:22:03 PST 2018
Certificate fingerprints:
MD5: 61:57:B5:6B:56:08:B9:ED:E8:EC:EC:85:A9:CA:1A:F4
SHA1: 75:1B:86:CD:1E:34:7C:13:2F:49:E2:6D:73:A0:4F:05:09:11:7B:72
SHA256: EB:FA:E4:3F:CB:22:31:9F:97:7B:FA:E4:79:D6:90:7F:E0:20:3E:DA:E8:6F:C3:F0:38:55:F7:C0:1E:0D:6A:33
Signature algorithm name: SHA256withRSA
Version: 3
....
Trust this certificate? [no]: yes
Certificate was added to keystore
通过阅读手册页,keytools调用将变得清晰。总结一下:-import
命令keytools添加证书,-alias
给出存储中证书的标题,-file
给出从中读取证书的文件的路径,-keystore
给出密钥库的路径(没有它,将使用默认的~/. keystore
),-store pass
给出该密钥库的密码。您可以添加选项-no提示符
以减少工具的注释,并添加选项-Trust cacerts
以停止有关信任证书的问题,但对于这样的使用,我喜欢进行交叉检查。
如果您愿意,相同的调用将导入根CA证书。
接下来,我们测试更改是否有效。再次尝试在LiClipse下使用EGit从ffmpeg.org执行“git拉取”。这一次,没有出现错误对话框。这表明JRE的安全代码将信任链中的证书从git.ffmpeg.org服务器的证书连接到JRE信任存储中的某个证书。(如果您在JRE信任存储中安装了服务器的证书,那么这是一个1证书链。)
这是我写的一篇关于如何向LiClipse添加SSL证书以允许EGit访问git repo的博客文章的浓缩。