https ssl java_java开发https请求ssl不受信任问题解决方法

导读热词

本文主要讨论的是java开发https请求ssl不受信任的解决方法,具体分析及实现代码如下。

在java代码中请求https链接的时候,可能会报下面这个错误

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

原因是没有证书。在浏览器中直接使用url访问是可以的,应该是浏览器之前就保存过对应的.cer证书。

解决方法有两种,从目标机器获得有效证书或者忽略证书信任问题。

一、获得目标机器有效证书

1、编译安装证书程序 javac InstallCert.java(代码如下)

/*

* Copyright 2006 Sun Microsystems,Inc. All Rights Reserved.

*

* Redistribution and use in source and binary forms,with or without

* modification,are permitted provided that the following conditions

* are met:

*

* - Redistributions of source code must retain the above copyright

* notice,this list of conditions and the following disclaimer.

*

* - Redistributions in binary form must reproduce the above copyright

* notice,this list of conditions and the following disclaimer in the

* documentation and/or other materials provided with the distribution.

*

* - Neither the name of Sun Microsystems nor the names of its

* contributors may be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS

* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT LIMITED TO,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

* CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT,INCIDENTAL,SPECIAL,* EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA,OR

* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

* LIABILITY,WHETHER IN CONTRACT,STRICT LIABILITY,OR TORT (INCLUDING

* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

* SOFTWARE,EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/**

* http://blogs.sun.com/andreas/resource/InstallCert.java

* Use:

* java InstallCert hostname

* Example:

*% java InstallCert ecc.fedora.redhat.com

*/

import javax.net.ssl.*;

import java.io.*;

import java.security.KeyStore;

import java.security.MessageDigest;

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

/**

* Class used to add the server's certificate to the KeyStore

* with your trusted certificates.

*/

public class InstallCert {

public static void main(String[] args) throws Exception {

String host;

int port;

char[] passphrase;

if ((args.length == 1) || (args.length == 2)) {

String[] c = args[0].split(":");

host = c[0];

port = (c.length == 1) ? 443 : Integer.parseint(c[1]);

String p = (args.length == 1) ? "changeit" : args[1];

passphrase = p.tocharArray();

} else {

System.out.println("Usage: java InstallCert [:port] [passphrase]");

return;

}

File file = new File("jssecacerts");

if (file.isFile() == false) {

char SEP = File.separatorchar;

File dir = new File(System.getProperty("java.home") + SEP

+ "lib" + SEP + "security");

file = new File(dir,"jssecacerts");

if (file.isFile() == false) {

file = new File(dir,"cacerts");

}

}

System.out.println("Loading KeyStore " + file + "...");

InputStream in = new FileInputStream(file);

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

ks.load(in,passphrase);

in.close();

SSLContext context = SSLContext.getInstance("TLS");

TrustManagerFactory tmf =

TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

tmf.init(ks);

X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];

SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);

context.init(null,new TrustManager[]{

tm

},null);

SSLSocketFactory factory = context.getSocketFactory();

System.out.println("opening connection to " + host + ":" + port + "...");

SSLSocket socket = (SSLSocket) factory.createSocket(host,port);

socket.setSoTimeout(10000);

try {

System.out.println("Starting SSL handshake...");

socket.startHandshake();

socket.close();

System.out.println();

System.out.println("No errors,certificate is already trusted");

}

catch (SSLException e) {

System.out.println();

e.printStackTrace(System.out);

}

X509Certificate[] chain = tm.chain;

if (chain == null) {

System.out.println("Could not obtain server certificate chain");

return;

}

BufferedReader reader =

new BufferedReader(new InputStreamReader(System.in));

System.out.println();

System.out.println("Server sent " + chain.length + " certificate(s):");

System.out.println();

MessageDigest sha1 = MessageDigest.getInstance("SHA1");

MessageDigest md5 = MessageDigest.getInstance("MD5");

for (int i = 0; i < chain.length; i++) {

X509Certificate cert = chain[i];

System.out.println

(" " + (i + 1) + " Subject " + cert.getSubjectDN());

System.out.println(" Issuer " + cert.getIssuerDN());

sha1.update(cert.getEncoded());

System.out.println(" sha1 " + toHexString(sha1.digest()));

md5.update(cert.getEncoded());

System.out.println(" md5 " + toHexString(md5.digest()));

System.out.println();

}

System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");

String line = reader.readLine().trim();

int k;

try {

k = (line.length() == 0) ? 0 : Integer.parseint(line) - 1;

}

catch (NumberFormatException e) {

System.out.println("KeyStore not changed");

return;

}

X509Certificate cert = chain[k];

String alias = host + "-" + (k + 1);

ks.setCertificateEntry(alias,cert);

OutputStream out = new FileOutputStream("jssecacerts");

ks.store(out,passphrase);

out.close();

System.out.println();

System.out.println(cert);

System.out.println();

System.out.println

("Added certificate to keystore 'jssecacerts' using alias '"

+ alias + "'");

}

private static final char[] HEXDIGITS = "0123456789abcdef".tocharArray();

private static String toHexString(byte[] bytes) {

StringBuilder sb = new StringBuilder(bytes.length * 3);

for (int b : bytes) {

b &= 0xff;

sb.append(HEXDIGITS[b >> 4]);

sb.append(HEXDIGITS[b & 15]);

sb.append(' ');

}

return sb.toString();

}

private static class SavingTrustManager implements X509TrustManager {

private final X509TrustManager tm;

private X509Certificate[] chain;

SavingTrustManager(X509TrustManager tm) {

this.tm = tm;

}

public X509Certificate[] getAcceptedIssuers() {

throw new UnsupportedOperationException();

}

public void checkClientTrusted(X509Certificate[] chain,String authType)

throws CertificateException {

throw new UnsupportedOperationException();

}

public void checkServerTrusted(X509Certificate[] chain,String authType)

throws CertificateException {

this.chain = chain;

tm.checkServerTrusted(chain,authType);

}

}

}

2、运行安装证书程序生成证书

java InstallCert my.hoolai.com

例如:java InstalCert smtp.zhangsan.com:465 admin如果不加参数password和host的端口号,上面的获取证书程序中默认给的端口号是:443,密码是:changeit

3、根据运行提示信息,输入1,回车,在当前目录下生成名为: jssecacerts 的证书

将证书放置到$JAVA_HOME/jre/lib/security目录下, 切记该JDK的jre是工程所用的环境!!!

或者:

System.setProperty("javax.net.ssl.trustStore","你的jssecacerts证书路径");

可以更改密码,在security目录下运行命令

keytool -storepasswd -new xxxcom -keystore cacerts

就可以修改密码,修改后使用命令

keytool -list -v -keystore cacerts

查看文件的信息,会提示需要密码才能查看,如果输入密码与修改后的密码匹配,说明修改成功了。

PS:至此这种方式可以成功使用ssl了,另外再补充一下,根据刚才生成的文件jssecacerts,可以生成cer文件,

命令如下

keytool -export -alias xxx.com-1 -keystore jssecacerts -rfc -file xxx.cer

如上,之前的工具类中默认命名别名是加上"-1"。使用InstallCert设置的密码需要跟cacerts文件中的密码一致,

如果修改过密码,就需要修改InstallCert类中对应的密码字符串,否则会有下面这个异常:

java.security.UnrecoverableKeyException: Password verification Failed

二、忽略证书信任问题

源码:http://mengyang.iteye.com/blog/575671

一定要注意需要在connection创建之前调用文章里所述的方法,像这个样子:

trustAllHttpsCertificates();

HostnameVerifier hv = new HostnameVerifier() {

public boolean verify(String urlHostName,SSLSession session) {

return true;

}

};

HttpsURLConnection.setDefaultHostnameVerifier(hv);

connection = (HttpURLConnection) url.openConnection();

好吧,两种方法都试过有效。

总结

以上就是本文关于java开发https请求ssl不受信任问题解决方法的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值