tomcat+https协议的接口编写及客户端访问

https无非就是http+ssl,也就是在http基础上进行证书上的校验,俗称安全的http,其实就是配置服务器的访问方式

具体操作步骤:

1.对服务端进行修改,接口访问使用https

      a.利用jdk自带的证书生成工具来生成一个key :  (生成证书等资料见后附)

keytool -genkeypair -alias certificatekey -keyalg RSA -validity 365 -keystore shfqkeystore.jks

      

                          主意一下:'您的名字与姓氏是什么'这里需要注意的,你所填的到时会作为是你的域名来用

命令详解
keytool -genkeypair -alias certificatekey -keyalg RSA -validity 365 -keystore shfqkeystore.jks
生成keystore后接着生成一个密钥对儿。RSA是非对称密钥算法,也可以改为 keytool支持的其他密钥算法,365代表的是证书的有效期,可以自己指定,shfqkeystore.jks是keystroe的名称,也可以自己指定。

     b.tomcat/conf/server.xml启用ssl(把下面的这个本身是注释掉的开启)

      

    c.把上面tomcat配置进行修改(添加:keystoreFile="对应你生成的key文件路径",keystorePass="你的秘钥口令"):

     

    d.ok这样就可以了,再来访问下之前做的接口地址,https://localhost:8443/springMVC/user/getUserByName/cwh,结果如下,证明ssl应用成功

    

   e.至此似乎服务端接口采用https协议很成功,但是问题来了,之前http://localhost:8080/springMVC/user/getUserByName/cwh这个地址已经暴露过,别人直接通过这个访问不也就绕过了https了么,那么解决办法就是让http访问重定向到https去,操作如下:在tomcat目录下的conf/web.xml此文件改位置添加如下代码代码:

     <security-constraint> 
      <web-resource-collection> 
      <web-resource-name>ssl</web-resource-name> 
      <url-pattern>/*</url-pattern> 
      </web-resource-collection> 
      <user-data-constraint> 
      <transport-guarantee>CONFIDENTIAL</transport-guarantee> 
      </user-data-constraint> 
    </security-constraint>

    

    ok这样的话继续访问http://localhost:8080/springMVC/user/getUserByName/cwh的话会被重定向到https去:

    至此https服务端完成

2.下面进行httpclient客户端编写,

      

https协议对于开发者而言其实只是多了一步证书验证的过程。这个证书正常情况下被jdk/jre/security/cacerts所管理。里面证书包含两种情况:

1、机构所颁发的被认证的证书,这种证书的网站在浏览器访问时https头显示为绿色如百度

2、个人所设定的证书,这种证书的网站在浏览器里https头显示为红色×,且需要点击信任该网站才能继续访问。而点击信任这一步的操作就是我们在java代码访问https网站时区别于http请求需要做的事情。

所以JAVA发送Https请求有两种情况,三种解决办法:

第一种情况:Https网站的证书为机构所颁发的被认证的证书,这种情况下和http请求一模一样,无需做任何改变,用HttpsURLConnection或者HttpURLConnection都可以

public static void main(String[] args) throws Exception{
        URL serverUrl = new URL("https://xxxx");
        HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-type", "application/json");
        //必须设置false,否则会自动redirect到重定向后的地址
        conn.setInstanceFollowRedirects(false);
        conn.connect();
        String result = getReturn(conn);
    }
 
    /*请求url获取返回的内容*/
    public static String getReturn(HttpURLConnection connection) throws IOException{
        StringBuffer buffer = new StringBuffer();
        //将返回的输入流转换成字符串
        try(InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            String result = buffer.toString();
            return result;
        }
}
第二种情况:个人所设定的证书,这种证书默认不被信任,需要我们自己选择信任,信任的办法有两种:

A、将证书导入java的运行环境中

从该网站下载或者从网站开发者出获取证书cacert.crt
运行命令将证书导入java运行环境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file cacert.crt -alias xxx
完成。java代码中发送https的请求和http一样,同第一种情况。
B、忽略证书验证过程,忽略之后任何Https协议网站皆能正常访问,同第一种情况

/*
 * Title:         V100R001C00<br>
 * Description:  [描述模块的功能、作用、使用方法和注意事项]<br>
 * Copyright:    Copyright (c) 1988-2015<br>
 * Company:      Huawei Tech. Co., Ltd<br>
 * @author       
 * @version      1.0  2019年2月21日
 */
package com.example.vue.controller;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * <br>
 * 
 * @see    [相关类,可选、也可多条,对于重要的类或接口建议注释]
 * @since   V100R001C00, 2019年2月21日
 */
public  class MyTrustManager implements X509TrustManager {

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

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

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }
       
        
        public static void main(String[] args) throws Exception{
            //忽略证书过程
         SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");
         sslcontext.init(null, new TrustManager[]{new MyTrustManager()}, new java.security.SecureRandom());
            //不校验主机名
         HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
          public boolean verify(String s, SSLSession sslsession) {
          return true;
          }
         };
         HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
         HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
       //创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
         URL reqURL = new URL("https://127.0.0.1:8888/test" ); //创建URL对象
         HttpsURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection();
         
         /*下面这段代码实现向Web页面发送数据,实现与网页的交互访问
          // 发送POST请求必须设置如下两行,如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false
            huconn.setDoOutput(true);
            //如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true
            huconn.setDoInput(true);
            //设置POST方式连接
            huconn.setRequestMethod("POST");
            //创建头信息map迭代器  headMap为Map类型参数
            Iterator it = headMap.keySet().iterator();
            //设置请求头配置信息
            while (it.hasNext()) {
            String key = it.next();
            String value = headMap.get(key);
            huconn.setRequestProperty(key, value);
        }
         OutputStreamWriter out = new OutputStreamWriter(huc.getOutputStream(), "8859_1");
         out.write( "……" );
         out.flush();
         out.close();
         */

         //取得该连接的输入流,以读取响应内容
         InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream());

         //读取服务器的响应内容并显示
         int respInt = insr.read();
         while( respInt != -1){
          System.out.print((char)respInt);
          respInt = insr.read();
         }   
     

}
}
 

C、java代码中加载证书,必须使用HttpsURLConnection方式

从网站开发者出获取生成证书的密钥库cacert.keystore
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
    /*
     * The default X509TrustManager returned by SunX509.  We'll delegate
     * decisions to it, and fall back to the logic in this class if the
     * default X509TrustManager doesn't trust it.
     */
    X509TrustManager sunJSSEX509TrustManager;
    MyX509TrustManager() throws Exception {
        // create a "default" JSSE X509TrustManager.
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(new FileInputStream("cancert.keystore"),
                "changeit".toCharArray());
        TrustManagerFactory tmf =
                TrustManagerFactory.getInstance("SunX509", "SunJSSE");
        tmf.init(ks);
        TrustManager tms [] = tmf.getTrustManagers();
            /*
             * Iterate over the returned trustmanagers, look
             * for an instance of X509TrustManager.  If found,
             * use that as our "default" trust manager.
             */
        for (int i = 0; i < tms.length; i++) {
            if (tms[i] instanceof X509TrustManager) {
                sunJSSEX509TrustManager = (X509TrustManager) tms[i];
                return;
            }
        }
            /*
             * Find some other way to initialize, or else we have to fail the
             * constructor.
             */
        throw new Exception("Couldn't initialize");
    }
    /*
     * Delegate to the default trust manager.
     */
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        try {
            sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
        } catch (CertificateException excep) {
            // do any special handling here, or rethrow exception.
        }
    }
    /*
     * Delegate to the default trust manager.
     */
    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        try {
            sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
        } catch (CertificateException excep) {
                /*
                 * Possibly pop up a dialog box asking whether to trust the
                 * cert chain.
                 */
        }
    }
    /*
     * Merely pass this through.
     */
    public X509Certificate[] getAcceptedIssuers() {
        return sunJSSEX509TrustManager.getAcceptedIssuers();
    }
}
public static void main(String[] args) throws Exception{
        SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");
        sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());
        URL serverUrl = new URL("https://xxxx");
        HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();
        conn.setSSLSocketFactory(sslcontext.getSocketFactory());
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-type", "application/json");
        //必须设置false,否则会自动redirect到重定向后的地址
        conn.setInstanceFollowRedirects(false);
        conn.connect();
        String result = getReturn(conn);
    }
 
    /*请求url获取返回的内容*/
    public static String getReturn(HttpsURLConnection connection) throws IOException{
        StringBuffer buffer = new StringBuffer();
        //将返回的输入流转换成字符串
        try(InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            String result = buffer.toString();
            return result;
        }
}

来源:CSDN 
原文:https://blog.csdn.net/shumeng_xiaoyan/article/details/76503601 
版权声明:本文为博主原创文章,转载请附上博文链接!

附:   参考地址    https://blog.csdn.net/Cy_LightBule/article/details/86680149

验证] - jks是否可以用

keytool -list -v -keystore shfqkeystore.jks
导出证书:  keytool -export -alias certificatekey -keystore shfqkeystore.jks -rfc -file shfqcert.cer

Truststore的生成以及公钥证书的导入

把上一步生成的公钥证书shfqcert.cer导入到truststore中。

keytool -import -alias certificatekey -file shfqcert.cer  -keystore shfqtruststore.jks

验证truststore文件

  • 键入命令
keytool -list -v -keystore shfqtruststore.jks

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值