来自Java客户端的SSL错误,但在Firefox中有效
我只是在我的服务器上设置SSL证书。我很确定他们的设置是正确的。当转到来自Java客户端的SSL错误,但在Firefox中有效,java,ssl,Java,Ssl,我只是在我的服务器上设置SSL证书。我很确定他们的设置是正确的。当转到https://mydomain.com/myapp在浏览器中,页面正确加载,绿色锁显示在地址栏中 从Firefox>POSTER向这个HTTPSurl发帖,我得到了一个有效的回复 如果我从Java客户端执行相同的POST,则会出现以下错误: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path bui
https://mydomain.com/myapp
在浏览器中,页面正确加载,绿色锁显示在地址栏中
从Firefox>POSTER向这个HTTPS
url发帖,我得到了一个有效的回复
如果我从Java客户端执行相同的POST,则会出现以下错误:
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
在我的服务器上,我已将CA_根证书放在JAVA…/jre/lib/security/cacert密钥库中
这是我的Java客户端的发布代码
URL url = new URL(Global.SERVER_URL);
HttpsURLConnection connection = null;
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setReadTimeout(45000);
connection.setRequestProperty("Content-Type", "text/json");
connection.connect();
请注意:这不是自签名证书。它是由CA颁发的
我感觉Glassfish没有发送完整的证书链。我看了看浏览器得到的证书,它是完整的证书链。我查看了SSL错误,这只是中间证书,也是我的域的证书
如何让Glassfish发送完整的证书链
检查SSL链
openssl.exe s_客户端-连接mydomain.com:443
返回
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
Loading 'screen' into random state - done
CONNECTED(00000190)
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = US, ST = <edited>, L = <edited>, O = <edited>, OU = <edited>, CN = <edited>
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
Server certificate
-----BEGIN CERTIFICATE-----
<edited>
-----END CERTIFICATE-----
subject=/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
issuer=/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
No client certificate CA names sent
---
SSL handshake has read 1676 bytes and written 513 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: <edited>
Session-ID-ctx:
Master-Key: <edited>
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1410274974
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
read:errno=0
警告:无法打开配置文件:/usr/local/ssl/openssl.cnf
将“屏幕”加载到随机状态-完成
已连接(00000190)
深度=0 C=US,ST=,L=,O=,OU=,CN=
验证错误:num=20:无法获取本地颁发者证书
验证返回:1
深度=0 C=US,ST=,L=,O=,OU=,CN=
验证错误:num=27:证书不受信任
验证返回:1
深度=0 C=US,ST=,L=,O=,OU=,CN=
验证错误:num=21:无法验证第一个证书
验证返回:1
---
证书链
0s:/C=US/ST=/L=/O=/OU=/CN=
i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
服务器证书
-----开始证书-----
-----结束证书-----
subject=/C=US/ST=/L=/O=/OU=/CN=
发卡机构=/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
未发送客户端证书CA名称
---
SSL握手读取1676字节,写入513字节
---
新的TLSv1/SSLv3密码是ECDHE-RSA-AES128-GCM-SHA256
服务器公钥为2048位
支持安全的重新协商
压缩:无
扩展:无
SSL会话:
协议:TLSv1.2
密码:ECDHE-RSA-AES128-GCM-SHA256
会话ID:
会话ID ctx:
主密钥:
键Arg:无
PSK身份:无
PSK标识提示:无
SRP用户名:无
开始时间:1410274974
超时:300(秒)
验证返回代码:21(无法验证第一个证书)
---
读取:errno=0
解决方案
接受布鲁诺对该概念的回答
其他详情:
浏览器和Java使用不同的可信根证书集,默认情况下,浏览器从操作系统获取此信息,Java支持自己的列表,这就是为什么它在浏览器中可能是绿色的,而在Java中不支持 要检查哪些证书支持您的Java版本,请执行以下操作:
\bin\keytool-keystore“\lib\security\cacerts”-storepass changeit-list
如果您没有看到您的证书,只需将其添加到
\lib\security\cacerts
文件中。SSLHandshakeException:
当一个失败的连接看起来像这样时出现。通常表明存在某种类型的证书验证问题,很可能您的信任存储不包含它所需的受信任根证书。以及
指示客户端和服务器无法协商所需的安全级别。该连接不再可用
javax.net.ssl.SSLHandshakeException:
sun.security.validator.validator异常:PKIX路径生成
失败:sun.security.provider.certpath.SunCertPathBuilderException:
找不到请求目标的有效证书路径
使用下面的代码发送HTTP POST请求的详细示例
private void sendPost() throws Exception {
String url = "https://selfsolve.apple.com/wcResults.do";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("Content-Type", "text/json");
String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
如果响应代码为200,则表示状态良好。有关解决相同异常的更多详细信息,请参阅以下链接
---
证书链
0s:/C=US/ST=/L=/O=/OU=/CN=
i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---
与您在评论中所说的不同,根据此输出,您的服务器没有发送任何中间证书。证书链只有一个证书(位于位置0):服务器证书
在我的服务器上,我已将CA_根证书放在JAVA…/jre/lib/security/cacert密钥库中
在服务器端的信任库中添加中间证书不会对服务器提供的链产生影响(如果适用,它仅用于对客户端进行身份验证)
您需要确保使用完整链设置密钥存储库条目,如中所述,遵循与相同的过程
您在浏览器中看到的很可能是它重建的链,并且浏览器也可能知道这些中间CA证书,而JRE可能不知道这些证书(使用了不同的信任锚集):通过正确呈现完整链,您只会增加默认JRE接受服务器证书的机会。(请注意,您不需要在链中显示根CA证书本身,它不会造成伤害,但只是网络开销。)它是自签名证书吗?@bhowden它是由我的公司颁发的。CA是巴尔的摩网络信任根。不确定默认情况下是否在jvm信任中。在服务器上,我将其添加到jvm trustok。证书是否已列出
---
Certificate chain
0 s:/C=US/ST=<edited>/L=<edited>/O=<edited>/OU=<edited>/CN=<edited>
i:/O=Cybertrust Inc/CN=Cybertrust Public SureServer SV CA
---