实际开发过程中,服务器端是不需要多加代码处理的,因为ssl验证过程是由服务器(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>
服务器端,写了个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 + "]个客户端证书");
- for (int i = 0; i < count; i++) {
- out.println("客户端证书 [" + (++i) + "]: ");
- out.println("校验结果:" + verifyCertificate(certs[--i]));
- out.println("证书详细:\r" + certs[i].toString());
- }
- } else {
- if (SCHEME_HTTPS.equalsIgnoreCase(request.getScheme())) {
- out.println("这是一个HTTPS请求,但是没有可用的客户端证书");
- request.setAttribute("user", "username");
- out.println(request.getAttribute("user"));
- } else {
- out.println("这不是一个HTTPS请求,因此无法获得客户端证书列表 ");
- }
- }
- 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;
- }
客户端代码:
- /**
- * 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"; //密码
- private static final String KEY_STORE_TRUST_PASSWORD = "123456"; // 密码
- 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();
- }
- }
- }