最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)SSL雙向認(rèn)證的方法

 更新時(shí)間:2016年08月20日 15:48:49   作者:xiangqian0505  
這篇文章主要介紹了Java實(shí)現(xiàn)SSL雙向認(rèn)證的方法,實(shí)例分析了ssl認(rèn)證的原理與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下

本文實(shí)例講述了Java實(shí)現(xiàn)SSL雙向認(rèn)證的方法。分享給大家供大家參考,具體如下:

我們常見的SSL驗(yàn)證較多的只是驗(yàn)證我們的服務(wù)器是否是真實(shí)正確的,當(dāng)然如果你訪問的URL壓根就錯(cuò)了,那誰也沒有辦法。這個(gè)就是所謂的SSL單向認(rèn)證。

但是實(shí)際中,我們有可能還會(huì)驗(yàn)證客戶端是否符合要求,也就是給我們每個(gè)用戶頒發(fā)一個(gè)證書,比且每個(gè)數(shù)字證書都是唯一的,不公開的。這樣就能通過這個(gè)數(shù)字證書保證當(dāng)前訪問我服務(wù)器的這個(gè)用戶是經(jīng)過服務(wù)器認(rèn)可的,其他人不可訪問。

雙向認(rèn)證 從第一個(gè)層面上 確保了服務(wù)器 與客戶端 都是互相認(rèn)可的。那么他們之間要進(jìn)行通信,就會(huì)在通信協(xié)議上附加SSL協(xié)議,確保通信的內(nèi)容是加密的,即使是sniffer這樣的網(wǎng)絡(luò)嗅探工具看到的都是亂碼。以后給大家演示下不加密的情況下,用sniffer看到的是什么。恐怕這樣你就能提高警惕了。

以下內(nèi)容從網(wǎng)絡(luò)上摘抄 加以實(shí)際驗(yàn)證后修改的。

模擬場景:

Server端和Client端通信,需要進(jìn)行授權(quán)和身份的驗(yàn)證,即Client只能接受Server的消息,Server只能接受Client的消息。

實(shí)現(xiàn)技術(shù):

JSSE(Java Security Socket Extension)

是Sun為了解決在Internet上的安全通訊而推出的解決方案。它實(shí)現(xiàn)了SSL和TSL(傳輸層安全)協(xié)議。在JSSE中包含了數(shù)據(jù)加密,服務(wù)器驗(yàn)證,消息完整性和客戶端驗(yàn)證等技術(shù)。通過使用JSSE,開發(fā)人員可以在客戶機(jī)和服務(wù)器之間通過TCP/IP協(xié)議安全地傳輸數(shù)據(jù)。

為了實(shí)現(xiàn)消息認(rèn)證。

Server需要:

1)KeyStore: 其中保存服務(wù)端的私鑰
2)Trust KeyStore:其中保存客戶端的授權(quán)證書

同樣,Client需要:

1)KeyStore:其中保存客戶端的私鑰
2)Trust KeyStore:其中保存服務(wù)端的授權(quán)證書
在這里我還是推薦使用Java自帶的keytool命令,去生成這樣信息文件。當(dāng)然目前非常流行的開源的生成SSL證書的還有OpenSSL。OpenSSL用C語言編寫,跨系統(tǒng)。但是我們可能在以后的過程中用java程序生成證書的方便性考慮,還是用JDK自帶的keytool。

1)生成服務(wù)端私鑰,并且導(dǎo)入到服務(wù)端KeyStore文件中

keytool -genkey -alias serverkey -keystore kserver.keystore
過程中,分別需要填寫,根據(jù)需求自己設(shè)置就行

keystore密碼:123456
名字和姓氏:jin
組織單位名稱:none
組織名稱:none
城市或區(qū)域名稱:BJ
州或省份名稱:BJ
國家代碼:CN

serverkey私鑰的密碼,不填寫和keystore的密碼一致。這里千萬注意,直接回車就行了,不用修改密碼。否則在后面的程序中以及無法直接應(yīng)用這個(gè)私鑰,會(huì)報(bào)錯(cuò)。

就可以生成kserver.keystore文件

server.keystore是給服務(wù)端用的,其中保存著自己的私鑰

2)根據(jù)私鑰,導(dǎo)出服務(wù)端證書

keytool -export -alias serverkey -keystore kserver.keystore -file server.crt
server.crt就是服務(wù)端的證書

3)將服務(wù)端證書,導(dǎo)入到客戶端的Trust KeyStore中

keytool -import -alias serverkey -file server.crt -keystore tclient.keystore
tclient.keystore是給客戶端用的,其中保存著受信任的證書

采用同樣的方法,生成客戶端的私鑰,客戶端的證書,并且導(dǎo)入到服務(wù)端的Trust KeyStore中

1)keytool -genkey -alias clientkey -keystore kclient.keystore
2)keytool -export -alias clientkey -keystore kclient.keystore -file client.crt
3)keytool -import -alias clientkey -file client.crt -keystore tserver.keystore

如此一來,生成的文件分成兩組

服務(wù)端保存:kserver.keystore tserver.keystore
客戶端保存:kclient.keystore  tclient.kyestore

以下是通過Java Socket通信程序來驗(yàn)證我們生成的證書是否可用。

客戶端:

package examples.ssl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
/**
 * SSL Client
 *
 */
public class SSLClient {
 private static final String DEFAULT_HOST     = "127.0.0.1";
 private static final int DEFAULT_PORT     = 7777;
 private static final String CLIENT_KEY_STORE_PASSWORD  = "123456";
 private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";
 private SSLSocket   sslSocket;
 /**
  * 啟動(dòng)客戶端程序
  *
  * @param args
  */
 public static void main(String[] args) {
  SSLClient client = new SSLClient();
  client.init();
  client.process();
 }
 /**
  * 通過ssl socket與服務(wù)端進(jìn)行連接,并且發(fā)送一個(gè)消息
  */
 public void process() {
  if (sslSocket == null) {
   System.out.println("ERROR");
   return;
  }
  try {
   InputStream input = sslSocket.getInputStream();
   OutputStream output = sslSocket.getOutputStream();
   BufferedInputStream bis = new BufferedInputStream(input);
   BufferedOutputStream bos = new BufferedOutputStream(output);
   bos.write("Client Message".getBytes());
   bos.flush();
   byte[] buffer = new byte[20];
   bis.read(buffer);
   System.out.println(new String(buffer));
   sslSocket.close();
  } catch (IOException e) {
   System.out.println(e);
  }
 }
 /**
  * <ul>
  * <li>ssl連接的重點(diǎn):</li>
  * <li>初始化SSLSocket</li>
  * <li>導(dǎo)入客戶端私鑰KeyStore,導(dǎo)入客戶端受信任的KeyStore(服務(wù)端的證書)</li>
  * </ul>
  */
 public void init() {
  try {
   SSLContext ctx = SSLContext.getInstance("SSL");
   KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
   TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
   KeyStore ks = KeyStore.getInstance("JKS");
   KeyStore tks = KeyStore.getInstance("JKS");
   ks.load(new FileInputStream("E://kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());
   tks.load(new FileInputStream("E://tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
   kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
   tmf.init(tks);
   ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
   sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);
  } catch (Exception e) {
   System.out.println(e);
  }
 }
}

服務(wù)器端:

package examples.ssl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;
/***********************************************************************************************************************
 * <ul>
 * <li>1)生成服務(wù)端私鑰</li>
 * <li>keytool -genkey -alias serverkey -keystore kserver.keystore</li>
 * <li>2)根據(jù)私鑰,到處服務(wù)端證書</li>
 * <li>keytool -exoport -alias serverkey -keystore kserver.keystore -file server.crt</li>
 * <li>3)把證書加入到客戶端受信任的keystore中</li>
 * <li>keytool -import -alias serverkey -file server.crt -keystore tclient.keystore</li>
 * </ul>
 **********************************************************************************************************************/
/**
 * SSL Server
 *
 */
public class SSLServer {
 private static final int DEFAULT_PORT     = 7777;
 private static final String SERVER_KEY_STORE_PASSWORD  = "123456";
 private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";
 private SSLServerSocket  serverSocket;
 /**
  * 啟動(dòng)程序
  *
  * @param args
  */
 public static void main(String[] args) {
  SSLServer server = new SSLServer();
  server.init();
  server.start();
 }
 /**
  * <ul>
  * <li>聽SSL Server Socket</li>
  * <li> 由于該程序不是演示Socket監(jiān)聽,所以簡單采用單線程形式,并且僅僅接受客戶端的消息,并且返回客戶端指定消息</li>
  * </ul>
  */
 public void start() {
  if (serverSocket == null) {
   System.out.println("ERROR");
   return;
  }
  while (true) {
   try {
    Socket s = serverSocket.accept();
    InputStream input = s.getInputStream();
    OutputStream output = s.getOutputStream();
    BufferedInputStream bis = new BufferedInputStream(input);
    BufferedOutputStream bos = new BufferedOutputStream(output);
    byte[] buffer = new byte[20];
    bis.read(buffer);
    System.out.println(new String(buffer));
    bos.write("Server Echo".getBytes());
    bos.flush();
    s.close();
   } catch (Exception e) {
    System.out.println(e);
   }
  }
 }
 /**
  * <ul>
  * <li>ssl連接的重點(diǎn):</li>
  * <li>初始化SSLServerSocket</li>
  * <li>導(dǎo)入服務(wù)端私鑰KeyStore,導(dǎo)入服務(wù)端受信任的KeyStore(客戶端的證書)</li>
  * </ul>
  */
 public void init() {
  try {
   SSLContext ctx = SSLContext.getInstance("SSL");
   KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
   TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
   KeyStore ks = KeyStore.getInstance("JKS");
   KeyStore tks = KeyStore.getInstance("JKS");
   ks.load(new FileInputStream("E://kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());
   tks.load(new FileInputStream("E://tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
   kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
   tmf.init(tks);
   ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
   serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
   serverSocket.setNeedClientAuth(true);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • quarzt定時(shí)調(diào)度任務(wù)解析

    quarzt定時(shí)調(diào)度任務(wù)解析

    這篇文章主要介紹了quarzt定時(shí)調(diào)度任務(wù),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • SpringBoot之spring.factories的使用方式

    SpringBoot之spring.factories的使用方式

    這篇文章主要介紹了SpringBoot之spring.factories的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java SpringMVC實(shí)現(xiàn)國際化整合案例分析(i18n)

    Java SpringMVC實(shí)現(xiàn)國際化整合案例分析(i18n)

    本篇文章主要介紹了Java SpringMVC實(shí)現(xiàn)國際化整合案例分析(i18n),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 關(guān)于Elasticsearch封裝公共索引增刪改查

    關(guān)于Elasticsearch封裝公共索引增刪改查

    索引是Elasticsearch中存儲(chǔ)數(shù)據(jù)的邏輯單元,類似于關(guān)系數(shù)據(jù)庫中的表,它包含多個(gè)文檔,每個(gè)文檔都是一個(gè)結(jié)構(gòu)化的JSON數(shù)據(jù)格式,在實(shí)際應(yīng)用中,索引的使用與配置可以依據(jù)不同的方案進(jìn)行,例如在Spring Boot項(xiàng)目中,可以選擇自動(dòng)配置或者手動(dòng)編寫配置類
    2024-10-10
  • Maven中兩個(gè)命令clean 和 install的使用

    Maven中兩個(gè)命令clean 和 install的使用

    Maven是一個(gè)項(xiàng)目管理和自動(dòng)構(gòu)建工具,clean命令用于刪除項(xiàng)目中由先前構(gòu)建生成的target目錄,install命令用于將打包好的jar包安裝到本地倉庫中,供其他項(xiàng)目依賴使用,下面就來詳細(xì)的介紹一下這兩個(gè)命令
    2024-09-09
  • 將Java的List結(jié)構(gòu)通過GSON庫轉(zhuǎn)換為JSON的方法示例

    將Java的List結(jié)構(gòu)通過GSON庫轉(zhuǎn)換為JSON的方法示例

    GONS是Google在GitHub上開源的Java類庫,提供各種Java對象和JSON格式對象之間的轉(zhuǎn)換功能,將Java的List結(jié)構(gòu)通過GSON庫轉(zhuǎn)換為JSON的方法示例
    2016-06-06
  • SpringBoot中處理日期的兩種方式小結(jié)

    SpringBoot中處理日期的兩種方式小結(jié)

    本文主要介紹了SpringBoot中處理日期的兩種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java多線程產(chǎn)生死鎖的必要條件

    Java多線程產(chǎn)生死鎖的必要條件

    今天小編就為大家分享一篇關(guān)于Java多線程產(chǎn)生死鎖的必要條件,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端發(fā)送消息的實(shí)例代碼

    SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端發(fā)送消息的實(shí)例代碼

    WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端發(fā)送消息的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • java循環(huán)遍歷無規(guī)則json的方式:gson、fastjson、orgjson

    java循環(huán)遍歷無規(guī)則json的方式:gson、fastjson、orgjson

    這篇文章主要介紹了java循環(huán)遍歷無規(guī)則json的方式:gson、fastjson、orgjson,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論

方正县| 搜索| 晋中市| 兴义市| 邵东县| 宣威市| 南召县| 洪雅县| 广东省| 修武县| 寿宁县| 鄂伦春自治旗| 巴马| 普兰店市| 阳泉市| 宁波市| 龙南县| 密山市| 黎城县| 富平县| 鄂州市| 阿拉善右旗| 班戈县| 象州县| 普陀区| 台中县| 长寿区| 耒阳市| 盐池县| 武隆县| 静乐县| 巨野县| 广西| 咸宁市| 哈巴河县| 漳州市| 闸北区| 汝城县| 尉犁县| 乐陵市| 枣强县|