一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java實現SSL雙向認證的方法

Java實現SSL雙向認證的方法

2020-06-05 15:18xiangqian0505 JAVA教程

這篇文章主要介紹了Java實現SSL雙向認證的方法,實例分析了ssl認證的原理與相關實現技巧,需要的朋友可以參考下

本文實例講述了Java實現SSL雙向認證的方法。分享給大家供大家參考,具體如下:

我們常見的SSL驗證較多的只是驗證我們的服務器是否是真實正確的,當然如果你訪問的URL壓根就錯了,那誰也沒有辦法。這個就是所謂的SSL單向認證。

但是實際中,我們有可能還會驗證客戶端是否符合要求,也就是給我們每個用戶頒發一個證書,比且每個數字證書都是唯一的,不公開的。這樣就能通過這個數字證書保證當前訪問我服務器的這個用戶是經過服務器認可的,其他人不可訪問。

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

以下內容從網絡上摘抄 加以實際驗證后修改的。

模擬場景:

Server端和Client端通信,需要進行授權和身份的驗證,即Client只能接受Server的消息,Server只能接受Client的消息。

實現技術:

JSSE(Java Security Socket Extension)

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

為了實現消息認證。

Server需要:

1)KeyStore: 其中保存服務端的私鑰
2)Trust KeyStore:其中保存客戶端的授權證書

同樣,Client需要:

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

1)生成服務端私鑰,并且導入到服務端KeyStore文件中

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

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

serverkey私鑰的密碼,不填寫和keystore的密碼一致。這里千萬注意,直接回車就行了,不用修改密碼。否則在后面的程序中以及無法直接應用這個私鑰,會報錯。

就可以生成kserver.keystore文件

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

2)根據私鑰,導出服務端證書

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

3)將服務端證書,導入到客戶端的Trust KeyStore中

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

采用同樣的方法,生成客戶端的私鑰,客戶端的證書,并且導入到服務端的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

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

服務端保存:kserver.keystore tserver.keystore
客戶端保存:kclient.keystore  tclient.kyestore

Java實現SSL雙向認證的方法

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

客戶端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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;
 /**
  * 啟動客戶端程序
  *
  * @param args
  */
 public static void main(String[] args) {
  SSLClient client = new SSLClient();
  client.init();
  client.process();
 }
 /**
  * 通過ssl socket與服務端進行連接,并且發送一個消息
  */
 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連接的重點:</li>
  * <li>初始化SSLSocket</li>
  * <li>導入客戶端私鑰KeyStore,導入客戶端受信任的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://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);
  }
 }
}

服務器端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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)生成服務端私鑰</li>
 * <li>keytool -genkey -alias serverkey -keystore kserver.keystore</li>
 * <li>2)根據私鑰,到處服務端證書</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;
 /**
  * 啟動程序
  *
  * @param args
  */
 public static void main(String[] args) {
  SSLServer server = new SSLServer();
  server.init();
  server.start();
 }
 /**
  * <ul>
  * <li>聽SSL Server Socket</li>
  * <li> 由于該程序不是演示Socket監聽,所以簡單采用單線程形式,并且僅僅接受客戶端的消息,并且返回客戶端指定消息</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連接的重點:</li>
  * <li>初始化SSLServerSocket</li>
  * <li>導入服務端私鑰KeyStore,導入服務端受信任的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();
  }
 }
}

希望本文所述對大家java程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 热99在线视频 | 国模娜娜a4u1546全套 | 亚洲毛片免费看 | 久久午夜一区二区 | 夫妇交换小说 | 99热r| 香蕉动漫库 | 午夜爱爱片 | 天天综合色天天综合色sb | 久久se视频精品视频在线 | 亚洲精品国产A久久久久久 亚洲精品福利一区二区在线观看 | 日韩亚洲欧美理论片 | 亚洲精品久久麻豆蜜桃 | 久久精品国产在热亚洲完整版 | 免费在线观看网址入口 | fc2成人免费共享视频 | 亚洲天天综合网 | 99只有精品| 亚洲成年www| 国产三级跑 | 性妲己| 果冻传媒mv在线观看入口免费 | 91在线免费看 | 我被黑人彻底征服的全文 | 男人扒开女人下身添 | 999久久免费高清热精品 | 国产精品1区2区 | 欧美一区二区免费 | 91在线视频免费观看 | 精品视频免费在线 | 99久久er这里只有精品17 | 被夫上司强迫中文 | 四虎免费看片 | 成年人免费在线看的惊悚动作片 | wc凹凸撒尿间谍女厕hd | 欧美成人二区 | 色猪视频 | 麻豆找网服 | 青青草原免费在线视频 | 亚洲精品色图 | 天天摸天天操天天爽 |