实际开发过程中,server端是不须要多加代码处理的,由于ssl验证过程是由server(tomcat、nginx等)完毕的。
这段代码也是參考了网上的:
新建一个web项目,项目结构和须要引入的jar例如以下:
web.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Secure Sockets Layer</display-name> <servlet> <servlet-name>SSLServlet</servlet-name> <servlet-class>com.sengle.cloud.servlet.SSLServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SSLServlet</servlet-name> <url-pattern>/sslServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- SSL配置 --> <security-constraint> <web-resource-collection> <web-resource-name>SSL</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <description>SSL required</description> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> </web-app>
server端,写了个servlet(注意配置到web.xml中)。代码例如以下:
import java.io.IOException; import java.io.PrintWriter; import java.security.cert.X509Certificate; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SSLServlet extends HttpServlet { private static final long serialVersionUID = 1601507150278487538L; private static final String ATTR_CER = "javax.servlet.request.X509Certificate"; private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; private static final String DEFAULT_ENCODING = "UTF-8"; private static final String SCHEME_HTTPS = "https"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); response.setCharacterEncoding(DEFAULT_ENCODING); PrintWriter out = response.getWriter(); X509Certificate[] certs = (X509Certificate[]) request.getAttribute(ATTR_CER); if (certs != null) { int count = certs.length; out.println("共检測到[" + count + "]个client证书"); for (int i = 0; i < count; i++) { out.println("client证书 [" + (++i) + "]: "); out.println("校验结果:" + verifyCertificate(certs[--i])); out.println("证书具体:\r" + certs[i].toString()); } } else { if (SCHEME_HTTPS.equalsIgnoreCase(request.getScheme())) { out.println("这是一个HTTPS请求。可是没有可用的client证书"); request.setAttribute("user", "username"); out.println(request.getAttribute("user")); } else { out.println("这不是一个HTTPS请求,因此无法获得client证书列表 "); } } out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } /** * <p> * 校验证书是否过期 * </p> * * @param certificate * @return */ private boolean verifyCertificate(X509Certificate certificate) { boolean valid = true; try { certificate.checkValidity(); } catch (Exception e) { e.printStackTrace(); valid = false; } return valid; }
client代码:
/** * Copyright (C) 2011-2014 sgcc Inc. * All right reserved. * modify info: */ package com.sengle.cloud.client; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.security.KeyStore; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; public class HttpsClient { private static final String KEY_STORE_TYPE_TRUST = "jks"; //假设证书为bks格式,那么要改为bks,同一时候以下的KEY_STORE_TYPE_CLIENT也要改为bks // private static final String KEY_STORE_TYPE_CLIENT = "PKCS12"; //假设KEY_STORE_TYPE_TRUST为jks,则KEY_STORE_TYPE_CLIENT为PKCS12 private static final String KEY_STORE_TYPE_CLIENT = "PKCS12"; //假设KEY_STORE_TYPE_TRUST为bks,则此处也应该为bks。 private static final String SCHEME_HTTPS = "https"; private static final int HTTPS_PORT = 8443; //此处为tomcat中的配置。默觉得8443 private static final String HTTPS_URL = "https://10.100.100.24:8443/SSL/sslServlet"; private static final String basePath = "D:/SSL/"; private static final String KEY_STORE_CLIENT_PATH = basePath + "/client-24.p12"; //假设为bks,那么此处应该为bks格式的证书 private static final String KEY_STORE_TRUST_PATH = basePath + "/client-24.truststore"; //假设为bks,那么此处应该为bks格式的证书 private static final String KEY_STORE_PASSWORD = "123456"; //password private static final String KEY_STORE_TRUST_PASSWORD = "123456"; // password public static void main(String[] args) throws Exception { ssl(); } private static void ssl() throws Exception { HttpClient httpClient = new DefaultHttpClient(); try { KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_CLIENT); KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_TRUST); InputStream ksIn = new FileInputStream(KEY_STORE_CLIENT_PATH); InputStream tsIn = new FileInputStream(new File(KEY_STORE_TRUST_PATH)); try { keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray()); trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray()); } finally { try { ksIn.close(); } catch (Exception ignore) {} try { tsIn.close(); } catch (Exception ignore) {} } //双向验证载入keystore和truststore两个证书 SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore); /* * 单向验证,仅仅载入truststore SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore); */ Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory); httpClient.getConnectionManager().getSchemeRegistry().register(sch); HttpGet httpget = new HttpGet(HTTPS_URL); System.out.println("executing request" + httpget.getRequestLine()); HttpResponse response = httpClient.execute(httpget); HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent())); String text; while ((text = bufferedReader.readLine()) != null) { System.out.println(text); } bufferedReader.close(); } EntityUtils.consume(entity); } finally { httpClient.getConnectionManager().shutdown(); } } }
时间: 2024-10-12 02:57:32