2
回答
keytool工具生成keystore时,cn写成ip后,通过浏览器能访问但是不能通过代码访问
终于搞明白,存储TCO原来是这样算的>>>   

大家好,关于https的一个问题,内容比较多,请大家耐心看看,Thx!

keytool工具生成keystore时,cn写成ip后,通过浏览器能访问但是不能通过代码访问,下面

1.生成keystore

keytool -genkeypair -alias test -keystore test.keystore -validity 30 -keyalg RSA -dname CN=192.168.1.214,OU=lr,O=jsb,L=jn,ST=s,C=86 -keypass 123456 -storepass 123456

2.导出证书

keytool -exportcert -alias test -file test.crt -keystore test.keystore -storepass 123456 -rfc

3.导入证书

keytool -importcert -alias test -file test.crt -keystore test.jks -storepass 123456 -trustcacerts -storetype JKS

这样我在代码中用test.jks来连接,下面是代码:

ClientHttpReq类:

package com.self.httpClient;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.mockito.internal.util.io.IOUtil;

import net.sf.json.JSONObject;

public class ClientHttpReq {

    public void httpsReq(){
        
        try {
            String params = "username=915719960&password=12346";
            TrustManager [] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new SecureRandom());
            SSLSocketFactory socketFactory = sslContext.getSocketFactory();
            URL url = new URL("https://192.168.1.214:8083/login");
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(3000);
            conn.setSSLSocketFactory(socketFactory);
            OutputStream out = conn.getOutputStream();
            out.write(params.getBytes());
            out.flush();
            out.close();
            InputStream input = conn.getInputStream();
            String result = IOUtils.toString(input);
            input.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

MyX509TrustManager类:

package com.self.httpClient;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class MyX509TrustManager implements X509TrustManager{

    X509TrustManager sunJSSEX509TrustManager;
    public MyX509TrustManager() {
        // TODO Auto-generated constructor stub
        KeyStore keyStore;//客户端验证服务端证书
        try {
            keyStore = KeyStore.getInstance("JKS");//客户端验证服务端证书
            keyStore.load(new FileInputStream("C:/test.jks"), "123456".toCharArray());
            TrustManagerFactory trustManageFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
            trustManageFactory.init(keyStore);
            TrustManager[] trustManage = trustManageFactory.getTrustManagers();
            for (int i = 0; i < trustManage.length; i++) {
                if(trustManage[i] instanceof X509TrustManager){
                    sunJSSEX509TrustManager = (X509TrustManager) trustManage[i];
                    return;
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // TODO Auto-generated method stub
//        sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // TODO Auto-generated method stub
        sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        // TODO Auto-generated method stub
        return sunJSSEX509TrustManager.getAcceptedIssuers();
    }

}

然后运行代码时就会出错:

java.security.cert.CertificateException: No subject alternative names present

如果是在浏览器上直接访问的话就不会有错,可以访问成功:访问方式:https://192.168.1.214:8083/loginGet(此处访问的是另一个接口)

举报
tomcat没配好哈 参照这个配试试
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" 
               maxThreads="150"
               scheme="https" secure="true" SSLEnabled="true"
               clientAuth="true" sslProtocol="TLS"
               keystoreFile="${catalina.home}/conf/server.keystore"
               keystorePass="changeit" truststoreFile="${catalina.home}/conf/server.keystore" truststorePass="changeit" 
			   URIEncoding="UTF-8"  sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
			   ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"
			   />



我也碰到这样的问题,应该是你生成证书的方式错了,参考

http://blog.csdn.net/id19870510/article/details/53954634

注:用jdk7+的keytool

顶部