<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ice world

    There is nothing too difficult if you put your heart into it.
    posts - 104, comments - 103, trackbacks - 0, articles - 0

    Java Tomcat SSL 服務端/客戶端雙向認證(一)

    Posted on 2012-06-04 17:36 IceWee 閱讀(32923) 評論(22)  編輯  收藏 所屬分類: JavaTomcat
    SSL——Secure Sockets Layer

    雙向認證(個人理解):
    客戶端認證:
    客戶端通過瀏覽器訪問某一網站時,如果該網站為HTTPS網站,瀏覽器會自動檢測系統中是否存在該網站的信任證書,如果沒有信任證書,瀏覽器一般會拒絕訪問,IE會有一個繼續訪問的鏈接,但地址欄是紅色,給予用戶警示作用,即客戶端驗證服務端并不是強制性的,可以沒有服務端的信任證書,當然是否繼續訪問完全取決于用戶自己。如何去除地址欄的紅色警告呢?后續會介紹導入服務端證書到瀏覽器的方法。

    服務端認證:
    服務端需要獲取到客戶端通過瀏覽器發送過來的認證證書,該證書在服務端的證書庫中已存在,僅僅是個匹配過程,匹配成功即通過認證,可繼續訪問網站資源,反之則無法顯示網頁,后續有截圖。

    基本邏輯:
    1、生成服務端密鑰庫并導出證書;
    2、生成客戶端密鑰庫并導出證書;
    3、根據服務端密鑰庫生成客戶端信任的證書;
    4、將客戶端證書導入服務端密鑰庫;
    5、將服務端證書導入瀏覽器。

    構建演示系統
    演示環境:
    JDK:1.6.0_32
    Tomcat:apache-tomcat-7.0.27
    開發工具:MyEclipse 10
    瀏覽器:Internet Explorer 9

    一、生成密鑰庫和證書
    可參考以下密鑰生成腳本,根據實際情況做必要的修改,其中需要注意的是:服務端的密鑰庫參數“CN”必須與服務端的IP地址相同,否則會報錯,客戶端的任意。
    key.script
    1、生成服務器證書庫

    keytool
    -validity 365 -genkey -v -alias server -keyalg RSA -keystore E:\ssl\server.keystore -dname "CN=127.0.0.1,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456


    2、生成客戶端證書庫

    keytool
    -validity 365 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore E:\ssl\client.p12 -dname "CN=client,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456


    3、從客戶端證書庫中導出客戶端證書

    keytool
    -export -v -alias client -keystore E:\ssl\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file E:\ssl\client.cer


    4、從服務器證書庫中導出服務器證書

    keytool
    -export -v -alias server -keystore E:\ssl\server.keystore -storepass 123456 -rfc -file E:\ssl\server.cer


    5、生成客戶端信任證書庫(由服務端證書生成的證書庫)

    keytool
    -import -v -alias server -file E:\ssl\server.cer -keystore E:\ssl\client.truststore -storepass 123456


    6、將客戶端證書導入到服務器證書庫(使得服務器信任客戶端證書)

    keytool
    -import -v -alias client -file E:\ssl\client.cer -keystore E:\ssl\server.keystore -storepass 123456


    7、查看證書庫中的全部證書

    keytool
    -list -keystore E:\ssl\server.keystore -storepass 123456


    二、Tomat配置
    使用文本編輯器編輯${catalina.base}/conf/server.xml
    找到Connector port="8443"的標簽,取消注釋,并修改成如下:
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
                   maxThreads
    ="150" scheme="https" secure="true"
                   clientAuth
    ="true" sslProtocol="TLS"
                   keystoreFile
    ="${catalina.base}/key/server.keystore" keystorePass="123456"
                   truststoreFile
    ="${catalina.base}/key/server.keystore" truststorePass="123456"/>

    備注:
    keystoreFile:指定服務器密鑰庫,可以配置成絕對路徑,如“D:/key/server.keystore”,本例中是在Tomcat目錄中創建了一個名稱為key的文件夾,僅供參考。
    keystorePass:密鑰庫生成時的密碼
    truststoreFile:受信任密鑰庫,和密鑰庫相同即可
    truststorePass:受信任密鑰庫密碼

    三、建立演示項目
    項目結構圖:
    項目名稱:SSL(隨意)


    SSLServlet.java
    package com.icesoft.servlet;

    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;

    /**
    * <p>
    * SSL Servlet
    * </p>
    *
    *
    @author IceWee
    * @date 2012-6-4
    *
    @version 1.0
    */

    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請求,但是沒有可用的客戶端證書");
                }
    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;
        }


    }


    web.xml
    說明:該演示項目強制使用了SSL,即普通的HTTP請求也會強制重定向為HTTPS請求,配置在最下面,可以去除,這樣HTTP和HTTPS都可以訪問。
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0"
        xmlns
    ="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation
    ="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    >
         
    <display-name>Secure Sockets Layer</display-name>   
       
       
    <servlet>
           
    <servlet-name>SSLServlet</servlet-name>
           
    <servlet-class>com.icesoft.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配置,即普通的請求也會重定向為SSL請求 --> 
       
    <security-constraint>
           
    <web-resource-collection>
               
    <web-resource-name>SSL</web-resource-name>
               
    <url-pattern>/*</url-pattern><!-- 全站使用SSL -->
           
    </web-resource-collection>
           
    <user-data-constraint>
               
    <description>SSL required</description>
               
    <!-- CONFIDENTIAL: 要保證服務器和客戶端之間傳輸的數據不能夠被修改,且不能被第三方查看到 -->
               
    <!-- INTEGRAL: 要保證服務器和client之間傳輸的數據不能夠被修改 -->
               
    <!-- NONE: 指示容器必須能夠在任一的連接上提供數據。(即用HTTP或HTTPS,由客戶端來決定)-->
               
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
           
    </user-data-constraint>
       
    </security-constraint>
    </web-app>


    index.jsp
    <%@ page language="java" pageEncoding="UTF-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>客戶端證書上傳</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">   
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/sslServlet" method="post">
       
    <input type="submit"  value="提交證書"/>
    </form>
    </body>
    </html>


    四、演示及配置
    發布演示項目,通過瀏覽器訪問:http://127.0.0.1:8080/SSLhttps://127.0.0.1:8443/SSL,得到相同的結果,如圖:






    得到如上結果的原始是因為客戶端沒有通過服務端的安全認證,接下來將服務端給客戶端頒發的證書導入到瀏覽器中:
    雙擊“client.p12”



    彈出窗口,下一步



    默認,下一步



    輸入生成密鑰時的密碼“123456”,下一步



    下一步



    完成



    成功



    再次訪問http://127.0.0.1:8080/SSLhttps://127.0.0.1:8443/SSL,彈出提示框:



    點擊確定后,IE瀏覽器自動阻止了繼續訪問,并給予警告提示,原因是瀏覽器中未導入該網站的可信證書





    點擊“繼續瀏覽此網站”,彈出提示,點擊確定



    哇!鮮紅的地址欄,夠醒目吧!你訪問的網站不安全那,親!



    點擊“提交證書”按鈕,返回正確結果!



    可以看出,客戶端并沒有服務端那么嚴格,只要未通過驗證就甭想訪問,下面將服務端生成的信任證書導入到瀏覽器的根證書中,這樣紅色的地址欄就會消失了!
    開始導入服務端信任證書,不能雙擊“server.cer”,需要手動導入到受信任的根證書機構中去。



    瀏覽器Internet選項-內容-證書



    點擊“受信任的根證書頒發機構”



    點擊“導入”



    下一步



    手動選擇“server.cer”,下一步






    下一步



    完成



    點“是”




    成功





    可以看到我們剛剛導入的根證書



    把所有瀏覽器窗口都關掉,再次訪問網站,發現鮮紅色已經逝去



    點擊“提交證書”按鈕,一切正常了,雙向認證的DEMO結束了!





    全文完!

    Feedback

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-08-18 17:54 by 愛學習的豬
    你好!我是這篇文章的讀者,我也是按照上面的方法配置好了tomcat,當我再次訪問http://127.0.0.1:8080/SSL或https://127.0.0.1:8443/SSL,彈出提示框,點擊確定后,不是進入的IE瀏覽器自動阻止了繼續訪問頁面,而是進入了網頁無法訪問頁面,這是怎么了呢?謝謝解答

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-09-07 10:04 by Jakey
    請問第5步中生成的 client.truststore 這個文件有什么用?

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-09-07 18:13 by IceWee
    @愛學習的豬
    你的瀏覽器沒有導入證書,所以直接就被拒絕了,客戶端不信任服務端,被瀏覽器自動阻止了

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-09-07 18:13 by IceWee
    @Jakey
    讓客戶端信任服務端的證書

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-11-20 17:50 by redocde
    看了N多的雙向配置SSL的教程,都是抄襲來抄襲去的,還是樓主的可用,一次成功.thanks

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-11-20 17:57 by redocde
    第五步是必須的嗎?將服務端證書導入到信任庫中,沒看懂什么意思.

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-11-21 09:59 by IceWee
    @redocde
    是的,并不是必須的,只是會有警示提示而已

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2012-12-24 21:30 by Francis
    你好,我照著你的這個做,成功了,表示感謝。
    不過我有一些問題,你在最開始提到的服務器和客戶端發來的證書做匹配,如果匹配不成功則不顯示頁面,這點沒見你的demo里面有,請問這點您做到了嗎?是在程序里面做還是修改服務器的一些配置?這點很好奇,如有結果希望您能答復一下

    另外還有一個小問題,就是客戶端的證書可以和IP綁定嗎?如果安全措施周全點的話會希望客戶端的證書只能是在指定IP上面使用,并不是所有客戶端都可以用一個證書。
    603005981@qq.com

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2013-04-12 14:16 by cc
    您好:
    樓主的語文水平真是高. 思路清晰、講解到位。肯定是大師級任務。
    請教老師一個問題:按照你演示demo操作配置 ,如果有了證書,以后的客戶端和服務端的數據交互就是安全的嗎?
    qq: 752184245@qq.com

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2013-05-20 16:31 by Sam
    最近在做一個需要證書和account&password共同驗證的一個功能,看了你的文章表示懂了很多,但還是有很多疑問,大師能加我QQ嗎?我相信以后我也會寫一篇類似文章去幫助更多的人。謝謝了。QQ:176128341

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2013-07-20 21:24 by 炮哥
    非常不錯。非常感謝

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2013-08-04 20:20 by landor
    非常詳細,完全copy就通過,非常感謝!

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2013-11-21 16:43 by sfw
    你好,按照您的方式確實能成功,但是我現在想改成用IP地址訪問,是不是只要修改服務端證書的CN=127.0.0.1為本機IP地址?我改為CN=192.168.0.11后測試不成功,彈出兩次確認證書界面后,直接跳到網頁無法訪問的界面

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2013-11-21 17:17 by sfw
    找到問題了,把IE重置就可以了,估計是之前有做過設置@sfw

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2013-12-16 10:56 by 張國印
    數據在傳輸過程中用的什么加密算法,如何查看呢?如果用的是對稱加密算法,加密秘鑰存儲在哪里呢?

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2014-04-24 18:16 by deng
    按照你的方法,果然成功了!非常感謝!

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2014-06-05 23:01 by jianzao
    你好,按照您的文章能看懂這個SSL配置,只是按你的測試項目運行時,進入servlet里,X509Certificate[] certs = (X509Certificate[]) request.getAttribute(ATTR_CER); certs的值總是為null,真不知道是什么原因.
    跪求解救!

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2014-09-06 11:49 by 1111
    技術貼,大贊一個

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2015-03-24 16:16 by liu
    @jianzao
    tomcat 里的server.xml有一個屬性clientAuth="false" 改為true

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)  回復  更多評論   

    2015-12-12 17:11 by shiguang0122
    步驟清除,講解清晰,常見錯誤解釋明白。
    由于以前不成功的嘗試,頁面總是打不開,后來看評論,重置瀏覽器,就可以了。

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2016-04-06 11:27 by luo
    牛掰,謝謝啦,辛苦了

    # re: Java Tomcat SSL 服務端/客戶端雙向認證(一)[未登錄]  回復  更多評論   

    2016-04-28 17:31 by su
    謝謝分享
    主站蜘蛛池模板: 久久国产乱子免费精品| 久久不见久久见中文字幕免费| 亚洲av无码成人黄网站在线观看| 亚洲免费视频网站| 亚洲日韩精品无码AV海量| 亚洲精品高清在线| 中文字幕在线免费| 一级A毛片免费观看久久精品| 日本久久久久亚洲中字幕| 国产高清免费在线| 777爽死你无码免费看一二区| 亚洲av日韩av永久在线观看 | 夫妻免费无码V看片| jizz免费在线观看| 亚洲ts人妖网站| 亚洲人成网77777亚洲色| 成人免费午夜无码视频| A毛片毛片看免费| 亚洲成熟丰满熟妇高潮XXXXX| 久久精品国产亚洲av麻| 国产又大又粗又硬又长免费| 亚洲视频免费一区| jizz免费观看| 国产成人不卡亚洲精品91| 亚洲人成高清在线播放| 久热综合在线亚洲精品| 全黄性性激高免费视频| 美女视频黄是免费的网址| 成人久久免费网站| 黄色一级免费网站| 亚洲妇女熟BBW| 亚洲av激情无码专区在线播放 | 亚洲精品无码mv在线观看网站 | 毛片A级毛片免费播放| 免费观看成人久久网免费观看| 蜜臀亚洲AV无码精品国产午夜.| 亚洲欧洲校园自拍都市| 国产亚洲免费的视频看| 亚洲成AV人网址| 午夜小视频免费观看| 无码国产精品一区二区免费式直播 |