前言
SSL协议在当今的网络信息传输过程中起到了不可替代的作用,使用不对称加密技术实现会话双方之间信息的安全传递,实现信息传递的保密性、完整性,并且会话双方能鉴别对方身份。
背景
在从plaintext到ssl加密的转换中我们经常会遇到ssl错误相关的问题,这在我们云通信IM这一块也是时常发生。所以在这里我们总结了几个客户经常遇见的问题,做了分析以及解决方案的介绍。
问题描述与分析
- 客户调用短信时出现证书错误:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
分析
此问题大致由于协议不匹配,实际上在客户端和服务器端都有可能发生,而且根据情形的不同,事实上可能并不值得修复。TLS 1.2在十年前问世,但仍然有一小部分网站不支持它。2018年8月份美国IETF最终将TLS 1.3发布为RFC 8446。我们建议如果可以,各个网站应当尽早添加对TLS 1.3的支持。PCI DSS也要求,所有收集支付卡信息的网站都必须结束对SSL 3.0和TLS 1.0的支持。今年(2020)3月四大浏览器制造商——谷歌、Firefox、苹果和微软——共同宣布弃用TLS 1.1。
例如以下情形:
客户端与服务器端所支持协议不同情况:
客户端 | 服务器端 |
---|---|
支持TLS 1.0, TLS 1.1 | 支持TLS 1.2 |
服务器不支持向后版本控制。但服务器不应该修复这个问题。客户端应该升级其浏览器,或者维持浏览器不变,但需对它进行配置以支持最新的TLS版本。
回到腾讯云通信这边,客户出现调用后台API出现类似问题大部分是由于,客户代码使用的runtime支持比较低版本的TLS1.0, 例如Java 7默认支持TLS 1.0.
解决方案
添加如下配置:
代码语言:txt复制System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
2. 客户调用短信时出现证书错误:
代码语言:txt复制javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
分析
这个问题的原因是根证书或者公有密钥丢失导致无法去认证。
解决方案
将根证书安装到JRE的truststore中,根证书可以在TencentQQAuthCA.crt 下载。
之后可以用一下命令进行配置:
代码语言:txt复制$ keytool -import -alias -ca -file /tmp/root_cert.cer -keystore cacerts
3. 客户遇到证书位置问题:
代码语言:txt复制[TencentCloudCommonExceptionTencentCloudSDKException]
code: message:cURL error 77: error setting certificate verify locations: CAfile: D:xxxxxxsslca-bundle.crt
CApath: none (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) requestId:NULL
分析
这个问题是ca证书被删掉或者不在默认路径,
解决方案
可以在服务器中找到ca-bundle.crt并复制到路径/etc/pki/tls/certs下面:
代码语言:txt复制mkdir -p /etc/pki/tls/certs
cp ca-bundle.crt /etc/pki/tls/certs
4. 客户调用接口出错:
代码语言:txt复制ProblemwiththeSSLCAcert(path?accessrights?)
分析
这里显示的是CA问题:颁发server证书的CA肯定是没有问题的(否则会造成大量瘫痪),那么应该是客户端使用的CA证书出现问题。
解决方案
- 重新安装
sudo yum install ca-certificates
- 有时系统CA包没有更新需要从网站(https://curl.haxx.se/docs/caextract.html)上下载最新的cacert.pem 然后重命名为/etc/ssl/certs/ca-certificates.crt:
$ curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem -O /root/ca-certificates.crt
$ cp cacert.pem /etc/ssl/certs/ca-certificates.crt
- 重启服务
5. 客户在用python调用的时候出错:
代码语言:txt复制[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)
分析
错误原因:Python2.7.9之后引入新特性,使用urllib.urlopen一个https时会验证SSL证书。当证书为self-sign证书时会报错
解决方案
设置为不验证
代码语言:txt复制import ssl
ssl._create_default_https_context = ssl._create_unverified_context
6. 客户在用java访问云API3.0接口报错:
代码语言:javascript复制[TencentCloudSDKException]code: message:javax.net.ssl.SSLException-java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty requestId
分析
错误原因:
- 证书的路径设置出错,找不到证书
- 权限问题,没有访问证书的权限
- 证书问题,没有证书或者被其他证书覆盖
解决方案
1. 参考:https://blog.csdn.net/weixin_43248279/article/details/102909555
代码语言:javascript复制1)sudo rm /etc/ssl/certs/java/cacerts #如果没有该文件 不管 直接进行下一步
2)sudo update-ca-certificates -f
3)reboot #重启即可
2. 如果以上方式不行,可以尝试添加腾讯云证书到java keystore.
将根证书安装到JRE的truststore中,根证书可以在TencentQQAuthCA.crt 下载。
之后可以用一下命令进行配置:
代码语言:javascript复制$ keytool -import -alias -ca -file /tmp/root_cert.cer -keystore cacerts
总结
SSL/TLS在现如今越来越重要,越来越广泛使用,与此同时出现的问题也是五花八门。我们希望能够尽量总结出一些常见的问题加以分析并提供给用户可以参考的解决方案。