转载:http://blog.csdn.net/faye0412/article/details/6883879
我是遇到接入国外支付要访问https 检查证书时解决的问题!
?
问题的根本是:
?
缺少安全证书时出现的异常。
?
解决问题方法:
?
将你要访问的webservice/url....的安全认证证书导入到客户端即可。
?
?
?
以下是获取安全证书的一种方法,通过以下程序获取安全证书:
?
[java] view plaincopy
class="dp-j">
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- import?java.io.BufferedReader;??
- import?java.io.File;??
- import?java.io.FileInputStream;??
- import?java.io.FileOutputStream;??
- import?java.io.InputStream;??
- import?java.io.InputStreamReader;??
- import?java.io.OutputStream;??
- import?java.security.KeyStore;??
- import?java.security.MessageDigest;??
- import?java.security.cert.CertificateException;??
- import?java.security.cert.X509Certificate;??
- ??
- import?javax.net.ssl.SSLContext;??
- import?javax.net.ssl.SSLException;??
- import?javax.net.ssl.SSLSocket;??
- import?javax.net.ssl.SSLSocketFactory;??
- import?javax.net.ssl.TrustManager;??
- import?javax.net.ssl.TrustManagerFactory;??
- import?javax.net.ssl.X509TrustManager;??
- ??
- 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?<host>[: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);??
- ????????}??
- ????}??
- ??
- }??
编译InstallCert.java,然后执行:java InstallCert hostname,比如:
java InstallCert www.twitter.com
会看到如下信息:
[java] view plaincopy
- java?InstallCert?www.twitter.com??
- Loading?KeyStore?/usr/java/jdk1.6.0_16/jre/lib/security/cacerts...??
- Opening?connection?to?www.twitter.com:443...??
- Starting?SSL?handshake...??
- ??
- 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??
- ????at?com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)??
- ????at?com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1476)??
- ????at?com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)??
- ????at?com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)??
- ????at?com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:846)??
- ????at?com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)??
- ????at?com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)??
- ????at?com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)??
- ????at?com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:815)??
- ????at?com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025)??
- ????at?com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1038)??
- ????at?InstallCert.main(InstallCert.java:63)??
- Caused?by:?sun.security.validator.ValidatorException:?PKIX?path?building?failed:?sun.security.provider.certpath.SunCertPathBuilderException:?unable?to?find?valid?certification?path?to?requested?target??
- ????at?sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)??
- ????at?sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)??
- ????at?sun.security.validator.Validator.validate(Validator.java:203)??
- ????at?com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)??
- ????at?InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:158)??
- ????at?com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)??
- ????at?com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:839)??
- ????...?7?more??
- Caused?by:?sun.security.provider.certpath.SunCertPathBuilderException:?unable?to?find?valid?certification?path?to?requested?target??
- ????at?sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)??
- ????at?java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)??
- ????at?sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)??
- ????...?13?more??
- ??
- Server?sent?2?certificate(s):??
- ??
- ?1?Subject?CN=www.twitter.com,?O=example.com,?C=US??
- ???Issuer??CN=Certificate?Shack,?O=example.com,?C=US??
- ???sha1????2e?7f?76?9b?52?91?09?2e?5d?8f?6b?61?39?2d?5e?06?e4?d8?e9?c7???
- ???md5?????dd?d1?a8?03?d7?6c?4b?11?a7?3d?74?28?89?d0?67?54???
- ??
- ?2?Subject?CN=Certificate?Shack,?O=example.com,?C=US??
- ???Issuer??CN=Certificate?Shack,?O=example.com,?C=US??
- ???sha1????fb?58?a7?03?c4?4e?3b?0e?e3?2c?40?2f?87?64?13?4d?df?e1?a1?a6???
- ???md5?????72?a0?95?43?7e?41?88?18?ae?2f?6d?98?01?2c?89?68???
- ??
- Enter?certificate?to?add?to?trusted?keystore?or?'q'?to?quit:?[1]??
输入1,回车,然后会在当前的目录下产生一个名为“ssecacerts”的证书。
将证书拷贝到$JAVA_HOME/jre/lib/security目录下,或者通过以下方式:
System.setProperty("javax.net.ssl.trustStore", "你的jssecacerts证书路径");
?
?
注意:因为是静态加载,所以要重新启动你的Web Server,证书才能生效。
?
参考知识:http://www.cnblogs.com/devinzhang/archive/2012/02/28/2371631.html