JAVA與C++進行sslsocket通訊,JAVA做服務端或客戶端
阿新 • • 發佈:2019-01-03
一、JAVA做服務端,讀取pem格式的證書和祕鑰
二、JAVA做客戶端,讀取pem格式證書和祕鑰<span style="font-size:18px;">public class SocketServer extends Thread{ private static final int SERVER_PORT = 10002; private SSLServerSocket serverSocket; public SocketServer() { // Initialize SSLServer try { //Load KeyStore And TrustKeyStore Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); //儲存服務端的私鑰 KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(null, null); // // 讀入服務端證書 PEMReader cacertfile = new PEMReader(new InputStreamReader( new FileInputStream("d:/cacert.pem"))); X509Certificate cacert = (X509Certificate) cacertfile.readObject(); Certificate[] certChain = new Certificate[1]; certChain[0] = cacert; cacertfile.close(); // 讀入私鑰 PEMReader kr = new PEMReader(new InputStreamReader(new FileInputStream("d:/privkey.pem"))); KeyPair key = (KeyPair) kr.readObject(); kr.close(); // 匯入服務端端私鑰和證書 keyStore.setKeyEntry("serverkey", key.getPrivate(), new char[]{}, certChain ); keyStore.setCertificateEntry("servercert", cacert); //Initialize KeyStore Factory 建立用於管理JKS金鑰庫的X.509金鑰管理器 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keyStore, "".toCharArray()); //Initialize SSLContext SSLContext context = SSLContext.getInstance("TLSv1"); //授權的金鑰管理器,用來授權驗證, context.init(keyManagerFactory.getKeyManagers(), null, null); //Set up Server Socket serverSocket = (SSLServerSocket) context. getServerSocketFactory().createServerSocket(SERVER_PORT); serverSocket.setWantClientAuth(false); //不需要客戶端證書 } catch (Exception e) { e.printStackTrace(); } } @Override public void run() { if(serverSocket == null){ System.out.println("Null server socket"); return; } try { Socket socket = serverSocket.accept(); //Receive From Client InputStream input = socket.getInputStream(); System.out.println("------Receive------"); //use byte array to initialize the output string System.out.println(new String(StreamToByteArray(input))); if(!socket.isClosed()){ //Response To Client OutputStream output = socket.getOutputStream(); output.write("服務端傳送123".getBytes()); output.flush(); socket.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * convert stream to Byte Array * @param inputStream * @return * @throws IOException */ public byte[] StreamToByteArray(InputStream inputStream) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int readIndex = inputStream.read(buffer); bout.write(buffer, 0, readIndex); bout.flush(); bout.close(); //inputStream.close(); return bout.toByteArray(); } public static void main(String[] args){ System.out.println("=======Start Server !======"); new SocketServer().run(); } } </span>
<span style="font-size:18px;">public class SocketClient2 { private Logger logger = LoggerFactory.getLogger(SocketClient2.class); private String tpath = Tools.getConfig("KeyPath");// 證書路徑 private String ip = Tools.getConfig("ip");// 服務端ip private int port = Integer.parseInt(Tools.getConfig("port"));// 埠 public static List<SSLSocket> socketList = new ArrayList<SSLSocket>(); public SSLSocket getSSlSocket() { SSLContext context = null; context = this.getSSLcontext(); SSLSocketFactory ssf = context.getSocketFactory(); try { SSLSocket ss = (SSLSocket) ssf.createSocket("127.0.0.1", 10002); String[] protocols = { "TLSv1" }; //設定客戶端協議 ss.setEnabledProtocols(protocols); return ss; } catch (UnknownHostException e) { logger.error("a{}", e); } catch (IOException e) { e.printStackTrace(); } return null; } private SSLContext getSSLcontext() { SSLContext sslContext = null; try { // 設定Security的Provider提供程式 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // System.setProperty("https.protocols", "SSLv3,SSLv2Hello"); // 建立空BKS,android只能用BKS(BouncyCastle密庫),一般java應用引數傳JKS(java自帶密庫) //訪問Java金鑰庫,JKS是keytool建立的Java金鑰庫,儲存金鑰。 KeyStore ksKeys = KeyStore.getInstance("JKS"); ksKeys.load(null, null); // 讀入客戶端證書 PEMReader cacertfile = new PEMReader(new InputStreamReader( new FileInputStream("d:/cacert.pem"))); X509Certificate cacert = (X509Certificate) cacertfile.readObject(); cacertfile.close(); // 匯入根證書作為trustedEntry //KeyStore.TrustedCertificateEntry 儲存可信的 Certificate 的 KeyStore 項。 KeyStore.TrustedCertificateEntry trustedEntry = new KeyStore.TrustedCertificateEntry( cacert); //用指定別名儲存 keystore Entry。 ksKeys.setEntry("ca_root", trustedEntry, null); // 構建TrustManager 建立用於管理JKS金鑰庫的X.509金鑰管理器。 TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");// 金鑰管理器 tmf.init(ksKeys); // 構建SSLContext,此處傳入引數為TLS,也可以為SSL sslContext = SSLContext.getInstance("TLSv1"); sslContext.init(null, tmf.getTrustManagers(), null); } catch (Exception e) { e.printStackTrace(); } return sslContext; } public static void main(String[] args) { SocketClient2 client = new SocketClient2(); SSLSocket ss =client.getSSlSocket(); try { ss.setSoTimeout(2000); OutputStream socketOut = null; if (ss != null && !ss.isClosed()) { socketOut = ss.getOutputStream(); socketOut.write("客戶端傳送".getBytes()); socketOut.flush(); } if (ss != null && !ss.isClosed()) { InputStream in; in = ss.getInputStream(); //input中的資料只能讀取一次 System.out.println(new String(StreamToByteArray(in))); } ss.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * convert stream to Byte Array * @param inputStream * @return * @throws IOException */ public static byte[] StreamToByteArray(InputStream inputStream) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int readIndex = inputStream.read(buffer); bout.write(buffer, 0, readIndex); bout.flush(); bout.close(); return bout.toByteArray(); } } </span>
三、證書
注:此服務端和客戶端可以進行通訊也可與C++進行通訊。