![如何通过命令行验证 SSL 指纹?(wget、curl 等)](https://linux22.com/image/820340/%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E5%91%BD%E4%BB%A4%E8%A1%8C%E9%AA%8C%E8%AF%81%20SSL%20%E6%8C%87%E7%BA%B9%EF%BC%9F%EF%BC%88wget%E3%80%81curl%20%E7%AD%89%EF%BC%89.png)
使用命令行网站下载程序,例如wget
,curl
或任何其他...在脚本中...
我有一个网站的 SHA-1 和 SHA-256 证书指纹。出于安全考虑(1)(2),我不想使用公共 SSL 证书颁发机构系统。指纹必须是硬编码的。
类似 wget 的应用程序可以检查 SSL 指纹吗?
wget 没有这样的功能。(3)
使用wget --ca-certificate
或者curl --cacert
我必须运行自己的本地证书颁发机构,但我想避免这种情况,因为这会增加很多复杂性。这也非常困难,以前没有人这样做过。(4)
没有任何工具,像
download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz https://site.com
?
当然,解决方案必须不能受到 TOCTOU 的影响。(5) MITM 可以让 openssl 客户端请求返回有效指纹,并篡改以下 wget 请求。
答案1
安装所需软件:
apt-get install ca-certificates curl
下载公共 SSL 证书:
openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt >./x.cert </dev/null
或更好:
echo -n | openssl s_client -connect torproject.org:443 -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./torproject.pem
获取SHA-1指纹:
openssl x509 -noout -in torproject.pem -fingerprint -sha1
获取SHA-256指纹:
openssl x509 -noout -in torproject.pem -fingerprint -sha256
手动比较 SHA-1 和 SHA-256 指纹torproject.org 常见问题解答:SSL。
.
可选择使 ca 证书在测试时无用。使用卷曲这里,但是获得有一个错误漏洞并且仍然使用 ca 文件。
sudo mv /usr/share/ca-certificates /usr/share/ca-certificates_
使用 curl 下载并固定证书:
curl --cacert ./torproject.pem https://check.torproject.org/ > check.html
答案2
在 tcsh 中:
echo | openssl s_client -connect host.example.com:443 |& openssl x509 -fingerprint -noout
答案3
这也足够了:
openssl x509 -fingerprint -in server.crt
答案4
#!/usr/bin/perl
# https://security.stackexchange.com/questions/20399/how-to-verify-the-ssl-fingerprint-by-command-line-wget-curl
# Code snippets taken from Net::SSLeay documentation and mildly modified.
# Requires a newer version of SSLeay (tested with 1.48)
# Needless to say, verify correct $host and $fingerprint before testing!!!
use Net::SSLeay qw(get_https3);
$host = "www.google.com";
$port = 443;
$fingerprint = "C1:95:6D:C8:A7:DF:B2:A5:A5:69:34:DA:09:77:8E:3A:11:02:33:58";
($p, $resp, $hdrs, $server_cert) = get_https3($host, $port, '/');
if (!defined($server_cert) || ($server_cert == 0)) {
warn "Subject Name: undefined, Issuer Name: undefined";
} elsif (Net::SSLeay::X509_get_fingerprint($server_cert, "sha1") ne $fingerprint) {
warn 'Invalid certificate fingerprint '
. Net::SSLeay::X509_get_fingerprint($server_cert, "sha1")
. ' for ' . Net::SSLeay::X509_NAME_oneline(
Net::SSLeay::X509_get_subject_name($server_cert));
} else {
print $p;
}
正如 Net::SSLeay 文档中所述,此方法意味着在 HTTP 事务之后进行验证,因此如果您想在向其发送数据之前验证您正在与正确的服务器通信,则不应使用此方法。但如果您所做的只是决定是否信任您刚刚下载的内容(从您的参考文献 #4 中听起来您就是这样),那么这种方法是可以的。