服務端
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(); } }}
用戶端
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); } }}
http://blog.csdn.net/xxb2008
JAVA調用HTTPS 連結
import javax.net.ssl.*;import java.io.*;import java.net.URL;import java.net.URLConnection;import java.security.KeyStore;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;/** * Created with . * Date: 14-4-10 * Time: 下午3:09 * To change this template use File | Settings | File Templates. */public class SSLHttpClient { public static void main(String[] args) { SSLHttpClient client = new SSLHttpClient(); client.connect(); } private void connect() { sendPost("https://localhost/index.jsp", "name1=value1&name2=value2"); } /** * 向指定URL發送POST方法的請求 * @param url 發送請求的URL * @param params 請求參數,請求參數應該是name1=value1&name2=value2的形式。 * @return URL所代表遠端資源的響應 */ public static String sendPost(String url, String params) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new SecureRandom()); HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection(); conn = (HttpsURLConnection) realUrl.openConnection(); // 開啟和URL之間的串連 conn.setSSLSocketFactory(context.getSocketFactory()); conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); // 設定通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); // 發送POST請求必須設定如下兩行 conn.setDoOutput(true); conn.setDoInput(true); // 擷取URLConnection對象對應的輸出資料流 out = new PrintWriter(conn.getOutputStream()); // 發送請求參數 out.print(params); // flush輸出資料流的緩衝 out.flush(); // 定義BufferedReader輸入資料流來讀取URL的響應 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += "\n" + line; } System.out.println(result); } catch (Exception e) { System.out.println("發送POST請求出現異常。" + e); e.printStackTrace(); } // 使用finally塊來關閉輸出資料流、輸入資料流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; }}class TrustAnyTrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }}class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { // 直接Pass,全部信任 return true; }}