Java完成SSL雙向認證的辦法。本站提示廣大學習愛好者:(Java完成SSL雙向認證的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是Java完成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 Socket通訊法式來驗證我們生成的證書能否可用。
客戶端:
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);
}
}
}
辦事器端:
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法式設計有所贊助。