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

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

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

    隨筆-124  評論-194  文章-0  trackbacks-0

    概念
    JAVA使用keystore文件來存儲所有KEY,keystore文件可以存放多個KEY,訪問它需要密碼。
    下面我介紹下如何將用OpenSSL做自簽名的證書一文中介紹的OpenSSL產(chǎn)生的KEY與JAVA的KEY轉(zhuǎn)換后使用,從而達(dá)到JAVA與OpenSSL通信的目的。


    用OpenSSL生成CA根證書,即(P1,V1)
    此步驟參見用OpenSSL做自簽名的證書一文


    在JAVA環(huán)境下生成自己的KEY,即(P2,V2)

    keytool -genkey -alias clientapp -keystore mycerts

    注意:這里會提示輸入訪問keystore的密碼,以及組織、城市、省份,一定要與CA根證書的一致,否則不能被CA簽名。


    從keystore中導(dǎo)出public key,即P2

    keytool -keystore mycerts -certreq -alias clientapp -file clientapp.crs


    用CA根證書為這個public key進(jìn)行簽名,即用V1給P2加密

    openssl ca -out clientapp.pem -config ./openssl.cnf -infiles?clientapp.crs
    ?

    轉(zhuǎn)換PEM到DER格式

    openssl x509 -in clientapp.pem -out clientapp.der -outform DER


    導(dǎo)入CA證書,即P1

    keytool -keystore mycerts -alias systemca -import -file cacert.pem


    導(dǎo)入用戶證書,即被V1加密過的P2

    keytool -keystore mycerts -alias clientapp -import -file clientapp.der

    注意:這里一定要先導(dǎo)入CA證書再導(dǎo)入用戶證書,否則會報(bào)錯。

    現(xiàn)在我們就生成了JAVA服務(wù)器使用的所有KEY了,在程序中將mycerts這個keystore導(dǎo)入就可以了。
    如果客戶端是使用OpenSSL的程序,那么用CA證書cacert.pem就能正常通信了,如果也是JAVA程序,那么我們需要將CA證書也轉(zhuǎn)換成keystore:

    keytool -import -keystore clikeystore -import -trustcacerts -file cacert.pem

    生成的clikeystore供JAVA客戶端使用,就能通信。


    再附上SVR和CLI的JAVA程序,我已經(jīng)用上面的KEY都測試通過:
    SVR端:

    import ?java.io. * ;
    import ?java.net. * ;
    import ?com.sun.net.ssl.KeyManagerFactory;
    import ?com.sun.net.ssl.KeyManager;
    import ?com.sun.net.ssl.TrustManagerFactory;
    import ?com.sun.net.ssl.TrustManager;
    import ?com.sun.net.ssl.SSLContext;
    import ?javax.net.ServerSocketFactory;
    import ?java.security.KeyStore;

    public ? class ?svr? implements ?Runnable {
    ??
    ??
    public ? static ? final ? int ?PORT? = ? 5555 ;
    ??
    public ? static ? final ?String?HOST? = ? " localhost " ;
    ??
    public ? static ? final ?String?QUESTION? = ? " Knock,?knock. " ;
    ??
    public ? static ? final ?String?ANSWER? = ? " Who's?there? " ;

    ??
    // ?The?new?constants?that?are?used?during?setup.
    ?? public ? static ? final ?String?KEYSTORE_FILE? = ? " mycerts " ; // "server_keystore";
    ?? public ? static ? final ?String?ALGORITHM? = ? " sunx509 " ;
    ??
    public ? static ? final ?String?PASSWORD? = ? " churchillobjects " ;
    ??
    ??
    public ? static ? void ?main(String[]?args) {
    ????
    new ?Thread( new ?svr()).start();
    ??}

    ??
    ??
    public ? void ?run() {
    ????ServerSocket?ss?
    = ? null ;
    ????
    try ? {

    ??????
    // ?Local?references?used?for?clarity.?Their?presence
    ??????
    // ?here?is?part?of?the?reason?we?need?to?import
    ??????
    // ?so?many?classes.
    ??????KeyManagerFactory?kmf;
    ??????KeyManager[]?km;
    ??????KeyStore?ks;
    ??????TrustManagerFactory?tmf;
    ??????TrustManager[]?tm;
    ??????SSLContext?sslc;
    ??????
    ??????
    // ?Create?a?keystore?that?will?read?the?JKS?(Java?KeyStore)
    ??????
    // ?file?format?which?was?created?by?the?keytool?utility.
    ??????ks? = ?KeyStore.getInstance( " JKS " );
    ??????
    ??????
    // ?Load?the?keystore?object?with?the?binary?keystore?file?and
    ??????
    // ?a?byte?array?representing?its?password.
    ??????ks.load( new ?FileInputStream(KEYSTORE_FILE),?PASSWORD.toCharArray());
    ??????
    ??????
    // ?Gives?us?a?factory?for?key?managers?that?will?let
    ??????
    // ?us?handle?the?asymetric?keys?we?created?earlier.
    ??????kmf? = ?KeyManagerFactory.getInstance(ALGORITHM);

    ??????
    // ?Initialize?the?key?manager?factory?with?the?keystore?object,
    ??????
    // ?again?using?the?same?password?for?security?since?it?is?going?to
    ??????
    // ?access?the?private?key.
    ??????kmf.init(ks,?PASSWORD.toCharArray());
    ??????
    ??????
    // ?Now?we?can?get?the?key?managers?from?the?factory,?since?it?knows
    ??????
    // ?what?type?we?are?using?now.
    ??????km? = ?kmf.getKeyManagers();
    ??????
    ??????
    // ?Next,?create?a?trust?manager?factory?using?the?same?algorithm.
    ??????
    // ?This?is?to?avoid?using?the?certificates?in?cacerts?that
    ??????
    // ?represent?an?authentication?security?risk.
    ??????tmf? = ?TrustManagerFactory.getInstance(ALGORITHM);
    ??????
    ??????
    // ?then?initialize?it?with?the?keystore?object.?This?time?we?don't
    ??????
    // ?need?the?keystore?password.?This?is?because?trusted?certificates
    ??????
    // ?are?not?a?sensitive?element?in?the?keystore,?unlike?the
    ??????
    // ?private?keys.
    ??????tmf.init(ks);
    ??????
    ??????
    // ?Once?that's?initialized,?get?the?trust?managers?from?the?factory.
    ??????tm? = ?tmf.getTrustManagers();
    ??????
    ??????
    // ?Almost?done,?we?need?a?context?object?that?will?get?our
    ??????
    // ?server?socket?factory.?We?specify?TLS?to?indicate?that?we?will
    ??????
    // ?need?a?server?socket?factory?that?supports?SSL.
    ??????sslc? = ?SSLContext.getInstance( " TLS " );
    ??????
    ??????
    // ?Initialize?the?context?object?with?the?key?managers?and?trust
    ??????
    // ?managers?we?got?earlier.?The?third?parameter?is?an?optional
    ??????
    // ?SecureRandom?object.?By?passing?in?null,?we?are?letting?the
    ??????
    // ?context?object?create?its?own.
    ??????sslc.init(km,?tm,? null );
    ??????
    ??????
    // ?Finally,?we?get?the?ordinary-looking?server?socket?factory
    ??????
    // ?from?the?context?object.
    ??????ServerSocketFactory?ssf? = ?sslc.getServerSocketFactory();
    ??????
    ??????
    // ?From?the?factory,?we?simply?ask?for?an?ordinary-looking
    ??????
    // ?server?socket?on?the?port?we?wish.
    ??????ss? = ?ssf.createServerSocket(PORT);

    ??????listen(ss);
    ????}

    ????
    catch (Exception?e) {
    ??????e.printStackTrace();
    ????}

    ????
    finally {
    ??????
    if (ss != null ) {
    ????????
    try {
    ??????????ss.close();
    ????????}

    ????????
    catch (IOException?e) {
    ??????????
    // ?oh,?well
    ????????}

    ??????}

    ??????System.exit(
    0 );
    ????}

    ??}

    ??
    ??
    static ? void ?listen(ServerSocket?ss)? throws ?Exception {
    ????System.out.println(
    " Ready?for?connections. " );
    ????
    while ( true ) {
    ??????Socket?s?
    = ?ss.accept();
    ??????BufferedWriter?bw?
    = ? new ?BufferedWriter(
    ????????
    new ?OutputStreamWriter(s.getOutputStream()));
    ??????BufferedReader?br?
    = ? new ?BufferedReader(
    ????????
    new ?InputStreamReader(s.getInputStream()));
    ??????String?q?
    = ?br.readLine();
    ??????
    if ( ! QUESTION.equals(q)) {
    ????????
    throw ? new ?RuntimeException( " Wrong?question:?\ "" ?+?q?+? " \ "" );
    ??????}

    ??????System.out.println(
    " Question:?\ "" ?+?q?+? " \ "" );
    ??????bw.write(ANSWER
    + " \n " );
    ??????bw.flush();
    ??????s.close();
    ????}

    ??}

    }


    CLI端程序:

    import ?java.io. * ;
    import ?java.net. * ;
    import ?com.sun.net.ssl.KeyManagerFactory;
    import ?com.sun.net.ssl.TrustManagerFactory;
    import ?com.sun.net.ssl.SSLContext;
    import ?java.security.KeyStore;
    import ?javax.net.SocketFactory;

    public ? class ?cli? implements ?Runnable {
    ??
    ??
    public ? static ? final ? int ?PORT? = ? 5555 ;
    ??
    public ? static ? final ?String?HOST? = ? " localhost " ;
    ??
    public ? static ? final ?String?KEYSTORE_FILE? = ? " clikeystore " ; // "client_keystore";
    ?? public ? static ? final ?String?ALGORITHM? = ? " sunx509 " ;
    ??
    public ? static ? final ?String?PASSWORD? = ? " churchillobjects " ;
    ??
    public ? static ? final ?String?QUESTION? = ? " Knock,?knock. " ;
    ??
    public ? static ? final ?String?ANSWER? = ? " Who's?there? " ;
    ??
    ??
    public ? static ? void ?main(String[]?args) {
    ????
    new ?Thread( new ?cli()).start();
    ??}

    ??
    ??
    public ? void ?run() {
    ????Socket?socket?
    = ? null ;
    ????
    try {
    ??????KeyManagerFactory?kmf;
    ??????KeyStore?ks;
    ??????TrustManagerFactory?tmf;
    ??????SSLContext?sslc;

    ??????kmf?
    = ?KeyManagerFactory.getInstance(ALGORITHM);
    ??????ks?
    = ?KeyStore.getInstance(? " JKS " ?);
    ??????ks.load(
    new ?FileInputStream(KEYSTORE_FILE),?PASSWORD.toCharArray());
    ??????kmf.init(ks,?PASSWORD.toCharArray());
    ??????tmf?
    = ?TrustManagerFactory.getInstance(ALGORITHM);
    ??????tmf.init(ks);
    ??????sslc?
    = ?SSLContext.getInstance( " TLS " );
    ??????sslc.init(kmf.getKeyManagers(),?tmf.getTrustManagers(),?
    null );

    ??????
    // ?The?process?is?different?from?here?on?the?client.?Instead?of
    ??????
    // ?getting?a?ServerSocketFactory,?we?ask?for?a?SocketFactory?from
    ??????
    // ?the?SSL?context.
    ??????SocketFactory?sf? = ?sslc.getSocketFactory();

    ??????
    // ?Then?we?get?the?socket?from?the?factory?and?treat?it
    ??????
    // ?as?if?it?were?a?standard?(plain)?socket.
    ??????socket? = ?sf.createSocket(HOST,?PORT);
    ????
    ??????doQuery(socket);
    ????}

    ????
    catch (Exception?e) {
    ??????e.printStackTrace();
    ????}

    ????
    finally {
    ??????
    if (socket != null ) {
    ????????
    try {
    ??????????socket.close();
    ????????}

    ????????
    catch (IOException?e) {
    ??????????
    // ?oh,?well
    ????????}

    ??????}

    ??????System.exit(
    0 );
    ????}

    ??}


    ??
    private ? void ?doQuery(Socket?s)? throws ?Exception {
    ????BufferedWriter?bw?
    = ? new ?BufferedWriter( new ?OutputStreamWriter(s.getOutputStream()));
    ????BufferedReader?br?
    = ? new ?BufferedReader( new ?InputStreamReader(s.getInputStream()));
    ????bw.write(QUESTION
    + " \n " );
    ????bw.flush();
    ????String?response?
    = ?br.readLine();
    ????
    if ( ! ANSWER.equals(response)) {
    ??????
    throw ? new ?RuntimeException( " Wrong?answer:?\ "" ?+?response?+? " \ "" );
    ????}

    ????System.out.println(
    " Got?the?right?answer:?\ "" ?+?response?+? " \ "" );
    ??}

    }




    以上方法主要參考了如下兩個網(wǎng)頁:

    http://www.churchillobjects.com/c/11201g.html

    http://mark.foster.cc/kb/openssl-keytool.html

    posted on 2006-12-03 12:36 我愛佳娃 閱讀(11850) 評論(7)  編輯  收藏 所屬分類: SSL

    評論:
    # re: 用OpenSSL與JAVA(JSSE)通信 2008-05-15 21:03 | 不不
    你好,你在另一片文章里這樣寫的:

    公私鑰:公鑰可以唯一解密私鑰加密過的數(shù)據(jù),反之亦然。
    SSL過程:需要兩對公私鑰(P1,V1),(P2,V2),假設(shè)通信雙方是A和B,B是服務(wù)器,A要確認(rèn)和它通信的是B:
    A->B: hello
    B->A: 用V2加密過的P1(即用戶證書,A就用P2解密出P1)
    A->B: ok
    B->A: 用V1加密的一段信息
    A->B: 用P1加密一個自動生成的K(用之前的P1解密成功這段信息則認(rèn)為B是可信的了)
    B->A: 用K加密的數(shù)據(jù)(之后兩對密鑰功能結(jié)束,由K來加解密數(shù)據(jù))
    這里,P2就是第3方的CA證書,由于非對稱加密很慢,所以公私鑰只是用來保證K的傳送安全,之后通信是用K的對稱加密算法來保證。

    為什么這里是P2是CA證書,而上面的例子里變成了P1是CA證書?我剛接觸SSL不太久,所以不是很懂。抱歉把你06年的東西都搬出來了!  回復(fù)  更多評論
      
    # re: 用OpenSSL與JAVA(JSSE)通信 2008-05-16 18:02 | 我愛佳娃
    上文描述的是:
    用OpenSSL生成CA根證書,即(P1,V1)
    在JAVA環(huán)境下生成自己的KEY,即(P2,V2)

    這里,P1,V1指代的是CA根證書,所以P1是CA證書,V1是簽名公司需要保密,專門用來給別人簽字的私鑰。

    而,我的另一篇文章提到:
    B->A: 用V2加密過的P1(即用戶證書,A就用P2解密出P1)

    這里,V2相當(dāng)于CA公司的私鑰,相當(dāng)于上邊的V1,P2自然就是CA證書了。也即,這兩篇文章在變量指代上正好反了,但內(nèi)容應(yīng)該都沒有問題。

      回復(fù)  更多評論
      
    # re: 用OpenSSL與JAVA(JSSE)通信 2008-11-20 11:15 | llp20_2000
    @我愛佳娃
    我愛娃娃,按照上文,用OPENSSL的私鑰 ./private/cakey.pem 為javatool的公鑰簽名請求"clientapp.crs"做簽名的時候,也就是執(zhí)行語句:
    openssl ca -out clientapp.pem -config ./openssl.cnf -infiles clientapp.crs
    結(jié)果如下:
    **************************************************
    [~~~~ CA]$ openssl ca -out clientapp.pem -config ./openssl.cnf -infiles clientapp.crs
    Using configuration from ./openssl.cnf
    Enter pass phrase for ./private/cakey.pem:
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    commonName :ASN.1 12:'liangleping'
    organizationName :ASN.1 12:'HuaWei'
    organizationalUnitName:ASN.1 12:'Develop'
    localityName :ASN.1 12:'Cheng Du'
    stateOrProvinceName :ASN.1 12:'Si Chuan'
    countryName :ASN.1 12:'ch'
    The countryName field needed to be the same in the
    CA certificate (ch) and the request (ch)
    ************************************************
    最后出現(xiàn):The countryName field needed to be the same in the
      回復(fù)  更多評論
      
    # re: 用OpenSSL與JAVA(JSSE)通信 2008-11-20 11:18 | llp20_2000
    接樓上,剛才少發(fā)了:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    最后出現(xiàn):The countryName field needed to be the same in the
    ....CA certificate (ch) and the request (ch)
    并且生成的clientapp.pem大小為0(零)k,因此不能由pem生成dem.不知是何原因?
    我反復(fù)對比過兩次輸入的countryName ,并且在javatool中都和Openssl生成時候都輸入全部一樣的公司,組織,城市,國家等,都是一樣的結(jié)果.而博主的另一文章,openssl做自簽名,用V1給 P2簽名是可以的.并且此時-infiles為 req.pem.
    新人,不熟悉openssl.請博主幫助
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  回復(fù)  更多評論
      
    # re: 用OpenSSL與JAVA(JSSE)通信 2008-11-22 08:24 | 我愛佳娃
    俺也不知為什么了。
    國名好像可以為空的,你試下為空的情況。
    另外,你的提示符為什么會多ASNXXX:commonName :ASN.1 12:
    如果解決了,請貼上來。  回復(fù)  更多評論
      
    # re: 用OpenSSL與JAVA(JSSE)通信 2009-02-03 11:25 | Jamie
    那是因?yàn)樗膐penssl.conf里對于CN的設(shè)定是match, 而非optional.
    countryName = match

    如下:
    [ policy_match ]
    countryName = match
    stateOrProvinceName = match
    organizationName = match
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional

    所以, 必須是匹配的才行.
    你可以改為optional來解決這個問題.  回復(fù)  更多評論
      
    # 7867 2009-11-25 05:32 | 周永松
    主站蜘蛛池模板: 国产亚洲精久久久久久无码| 久久精品国产亚洲Aⅴ蜜臀色欲| 午夜毛片不卡免费观看视频| 国产一级大片免费看| 亚洲国产精品不卡毛片a在线| 亚洲精品无码永久在线观看你懂的| 一区二区三区亚洲| 一本色道久久88—综合亚洲精品 | 亚洲精品无码av人在线观看 | 亚洲综合无码AV一区二区| 亚洲ⅴ国产v天堂a无码二区| 亚洲久悠悠色悠在线播放| 特级做a爰片毛片免费看| a毛看片免费观看视频| 97性无码区免费| 亚洲国模精品一区| 麻豆亚洲AV永久无码精品久久| 亚洲色最新高清av网站| 成人av片无码免费天天看| 国产免费不卡视频| 一级毛片直播亚洲| 亚洲黄色网址大全| 边摸边吃奶边做爽免费视频99| 国产精品区免费视频| 国产青草视频在线观看免费影院| 亚洲性猛交XXXX| 亚洲熟妇成人精品一区| 97人妻精品全国免费视频 | 皇色在线视频免费网站| 亚洲精品无码av天堂| 亚洲欧洲国产成人精品| 丰满少妇作爱视频免费观看| 国产精品免费网站| 国产gv天堂亚洲国产gv刚刚碰| 亚洲精品二三区伊人久久| 久久国产免费直播| 日本二区免费一片黄2019| 亚洲视屏在线观看| 一区在线免费观看| 性xxxx视频播放免费| 亚洲视频在线播放|