生活随笔
收集整理的這篇文章主要介紹了
java实现 SSL双向认证
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://avery-leo.iteye.com/blog/276096
實(shí)現(xiàn)技術(shù):
JSSE(Java Security Socket Extension)
是Sun為了解決在Internet上的實(shí)現(xiàn)安全信息傳輸?shù)慕鉀Q方案。它實(shí)現(xiàn)了SSL和TSL(傳輸層安全)協(xié)議。在JSSE中包含了數(shù)據(jù)加密,服務(wù)器驗(yàn)證,消息完整性和客戶(hù)端驗(yàn)證等技術(shù)。通過(guò)使用JSSE,可以在Client和Server之間通過(guò)TCP/IP協(xié)議安全地傳輸數(shù)據(jù)。
?
為了實(shí)現(xiàn)消息認(rèn)證。
Server需要:
1)KeyStore: 其中保存服務(wù)端的私鑰
2)Trust KeyStore:其中保存客戶(hù)端的授權(quán)證書(shū)
Client需要:
1)KeyStore:其中保存客戶(hù)端的私鑰
2)Trust KeyStore:其中保存服務(wù)端的授權(quán)證書(shū)
?
使用Java自帶的keytool命令,去生成這樣信息文件:
1)生成服務(wù)端私鑰,并且導(dǎo)入到服務(wù)端KeyStore文件中
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
2)根據(jù)私鑰,導(dǎo)出服務(wù)端證書(shū)
?
?
?
3)將服務(wù)端證書(shū),導(dǎo)入到客戶(hù)端的Trust KeyStore中
?
?
采用同樣的方法,生成客戶(hù)端的私鑰,客戶(hù)端的證書(shū),并且導(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
?
?
Server:
?
Java代碼??
package?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;?? ?? ? ? ? ?? public?class?Server?implements?Runnable{?? ?? ????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;?? ?? ????? ? ? ? ?? ????public?static?void?main(String[]?args)?{?? ????????Server?server?=?new?Server();?? ????????server.init();?? ????????Thread?thread?=?new?Thread(server);?? ????????thread.start();?? ????}?? ?? ????public?synchronized?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("------receive:--------"+new?String(buffer).toString());?? ?? ????????????????bos.write("yes".getBytes());?? ????????????????bos.flush();?? ?? ????????????????s.close();?? ????????????}?catch?(Exception?e)?{?? ????????????????System.out.println(e);?? ????????????}?? ????????}?? ????}?? ????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("src/ssl/kserver.keystore"),?SERVER_KEY_STORE_PASSWORD.toCharArray());?? ????????????tks.load(new?FileInputStream("src/ssl/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)?{?? ????????????System.out.println(e);?? ????????}?? ????}?? ?? ????public?void?run()?{?? ?????????? ????????start();?? ????}?? }?? ?
Client:
Java代碼??
package?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;?? ?? ? ? ? ? ?? public?class?Client?{?? ?? ????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;?? ?? ????? ? ? ? ?? ????public?static?void?main(String[]?args)?{?? ???????Client?client?=?new?Client();?? ????????client.init();?? ????????client.process();?? ????}?? ?? ??? ????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("1234567890".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);?? ????????}?? ????}?? ?? ?? ????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("src/ssl/kclient.keystore"),?CLIENT_KEY_STORE_PASSWORD.toCharArray());?? ????????????tks.load(new?FileInputStream("src/ssl/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);?? ????????}?? ????}?? ?? }?? ?
啟動(dòng)Server
?
啟動(dòng)Client,發(fā)送信息。
?
Server接收如下:正確解密
?
?
?
返回Client信息,如下:
?
?
?
?
如此,就完成了服務(wù)端和客戶(hù)端之間的基于身份認(rèn)證的交互。
client采用kclient.keystore中的clientkey私鑰進(jìn)行數(shù)據(jù)加密,發(fā)送給server。
server采用tserver.keystore中的client.crt證書(shū)(包含了clientkey的公鑰)對(duì)數(shù)據(jù)解密,如果解密成功,證明消息來(lái)自client,進(jìn)行邏輯處理。
server采用kserver.keystore中的serverkey私鑰進(jìn)行數(shù)據(jù)加密,發(fā)送給client。
client采用tclient.keystore中的server.crt證書(shū)(包含了serverkey的公鑰)對(duì)數(shù)據(jù)解密,如果解密成功,證明消息來(lái)自server,進(jìn)行邏輯處理。
如果過(guò)程中,解密失敗,那么證明消息來(lái)源錯(cuò)誤。不進(jìn)行邏輯處理。這樣就完成了雙向的身份認(rèn)證。
?
總結(jié)
以上是生活随笔為你收集整理的java实现 SSL双向认证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。