请求https错误: unable to find valid certification

当java客户端请求实现https协议的服务时,出现异常:'unable to find valid certificationpath to requested target'

是因为服务期端的证书没有被认证,需要做的是把服务端证书导入到javakeystore。可以附件中的java类实现。
上面一句感觉应该如此说:
是因为客户端证书在服务期端没有被认证,所以需要做的是把客户端证书导入到javakeystore,以便可以发送到服务端去认证。可以附件中的java类实现。这种错误出现在需要双向认证的https服务器这里,普通情况如果用httpclient,直接
Protocol.registerProtocol("https", newProtocol("https", new EasySSLProtocolSocketFactory(),443));
即可访问https服务。

使用方法:

#java InstallCert web_site_hostname(此为待访问地址)

这个java类会打开一个连接到你指定的host,开始握手过程。如果出现异常会打印到控制台并且会显示服务端所使用的证书,此时它会问你是否要把证书加入到你的keystore。如果你不想加,输入"q",否则输入"1".

 

当你输入"1"后,InstallCert.java会显示证书的有关信息,然后把证书导入到一个名为"jssecacerts"的keystore中(当前目录),只需要把这个文件拷贝到%JAVA_HOME/jre/lib/security目录中,重命名为"cacerts".

 

原文地址:http://wanglei0119.javaeye.com/blog/607046

 

类内容:

import java.io.*;
import java.net.URL;

import java.security.*;
import java.security.cert.*;

import javax.net.ssl.*;

public class InstallCert {

    publicstatic 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 = newSavingTrustManager(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 alreadytrusted");
 } catch (SSLException e) {
    System.out.println();
    e.printStackTrace(System.out);
 }

 X509Certificate[] chain = tm.chain;
 if (chain == null) {
    System.out.println("Could not obtain server certificatechain");
    return;
 }

 BufferedReader reader =
  new BufferedReader(newInputStreamReader(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 addto 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 = newFileOutputStream("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 + "'");
    }

    privatestatic final char[] HEXDIGITS ="0123456789abcdef".toCharArray();

    privatestatic 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();
    }

    privatestatic class SavingTrustManager implements X509TrustManager {

 private final X509TrustManager tm;
 private X509Certificate[] chain;

 SavingTrustManager(X509TrustManager tm){
    this.tm = tm;
 }

 public X509Certificate[] getAcceptedIssuers(){
    throw new UnsupportedOperationException();
 }

 public voidcheckClientTrusted(X509Certificate[] chain, String authType)
  throws CertificateException{
    throw new UnsupportedOperationException();
 }

 public voidcheckServerTrusted(X509Certificate[] chain, String authType)
  throws CertificateException{
    this.chain = chain;
    tm.checkServerTrusted(chain, authType);
 }
    }

}


参考资料:
http://www.blogjava.net/stone2083/archive/2007/12/20/169015.html
http://www.blogjava.net/stone2083/archive/2010/01/30/311328.html
http://www.cnblogs.com/codewater/articles/2182826.html
http://hwyellow.blog.163.com/blog/static/880662402008835594312/
http://hi.baidu.com/crashice/blog/item/ef3bf70d1137e6c67bcbe189

.html
http://www.ibm.com/developerworks/cn/java/j-customssl/


你可能感兴趣的:(网络安全编程)