Java中TLS连接报javax.net.ssl.SSLHandshakeException错误求助
服务器端SSLHandshakeException: Received fatal alert: bad_certificate问题
我查阅过类似帖子但未解决问题。我通过以下步骤生成自签名证书并配置:
- 生成服务器新密钥对:
keytool -genkey -alias test-tls-server -keystore TestServerKeyStore.jks -storetype JKS -keyalg RSA -sigalg SHA1withRSA -validity 365 - 导出服务器证书到cer文件:
keytool -export -alias test-tls-server -file test_server.cer -keystore TestServerKeyStore.jks - 创建客户端密钥库并导入服务器证书:
keytool -import -keystore TestClientKeyStore.jks -storetype JKS -alias test-tls-server -file test_server.cer
该证书为刻意生成的自签名证书。我已在两端配置密钥库路径和密码:
System.setProperty("javax.net.ssl.keyStore", <path_to_keystore_file>); System.setProperty("javax.net.ssl.keyStorePassword", <pass_to_keystore>);
尝试连接服务器时,客户端看似正常,但读取套接字时服务器端出现错误:
javax.net.ssl.SSLHandshakeException Exception message: Received fatal alert: bad_certificate
此前证书未过期时代码可正常运行,更换新证书后出现此问题,恳请帮助。
解决思路
修正客户端配置项
客户端应该配置信任库而非密钥库,当前错误使用javax.net.ssl.keyStore会导致客户端尝试用自身密钥库做身份验证,而非信任服务器证书。改为配置信任库:System.setProperty("javax.net.ssl.trustStore", <path_to_TestClientKeyStore.jks>); System.setProperty("javax.net.ssl.trustStorePassword", <pass_to_truststore>);校验证书一致性
用命令确认客户端导入的证书与服务器证书匹配:- 查看服务器证书指纹:
keytool -printcert -file test_server.cer - 查看客户端信任库中的证书信息:
keytool -list -v -keystore TestClientKeyStore.jks
对比两者的指纹、有效期等信息,确保没有导入旧证书。
- 查看服务器证书指纹:
更换安全的签名算法
SHA1withRSA在高版本JDK中属于弱签名算法,可能被拒绝。重新生成证书时改用SHA256withRSA:keytool -genkey -alias test-tls-server -keystore TestServerKeyStore.jks -storetype JKS -keyalg RSA -sigalg SHA256withRSA -validity 365之后重新导出证书并导入客户端信任库。
检查密钥密码配置
如果生成密钥对时设置了与密钥库不同的密钥密码,服务器端需额外添加:System.setProperty("javax.net.ssl.keyPassword", <key_pass>);否则服务器无法读取私钥,会触发证书错误。
内容的提问来源于stack exchange,提问作者warchiefbinar
相关产品推荐
相关产品推荐

