轻拔琴弦|java-websocket示例项目,可以直接使用( 六 )

使用SSL证书 , 来验证websocket登录package com.test.test2;class WebSocketChatClient extends WebSocketClient {public WebSocketChatClient(URI serverUri) {super(serverUri);}@Overridepublic void onOpen(ServerHandshake handshakedata) {System.out.println("Connected");}@Overridepublic void onMessage(String message) {System.out.println("got: " + message);}@Overridepublic void onClose(int code, String reason, boolean remote) {System.out.println("Disconnected");}@Overridepublic void onError(Exception ex) {ex.printStackTrace();}}public class SSLClientExample {/** Keystore with certificate created like so (in JKS format):**keytool -genkey -keyalg RSA -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry"*/public static void main(String[] args) throws Exception {WebSocketChatClient chatclient = new WebSocketChatClient(new URI("wss://localhost:8887"));// load up the key storeString STORETYPE = "JKS";String KEYSTORE = Paths.get("src", "test", "java", "org", "java_websocket", "keystore.jks").toString();String STOREPASSWORD = "storepassword";String KEYPASSWORD = "keypassword";KeyStore ks = KeyStore.getInstance(STORETYPE);File kf = new File(KEYSTORE);ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, KEYPASSWORD.toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(ks);SSLContext sslContext = null;sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);// sslContext.init( null, null, null ); // will use java's default key and trust store which is sufficient unless you deal with self-signed certificatesSSLSocketFactory factory = sslContext.getSocketFactory();// (SSLSocketFactory) SSLSocketFactory.getDefault();chatclient.setSocketFactory(factory);chatclient.connectBlocking();BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));while (true) {String line = reader.readLine();if (line.equals("close")) {chatclient.closeBlocking();} else if (line.equals("open")) {chatclient.reconnect();} else {chatclient.send(line);}}}} package com.test.test2;public class SSLServerExample {/** Keystore with certificate created like so (in JKS format):**keytool -genkey -keyalg RSA -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry"*/public static void main(String[] args) throws Exception {ChatServer chatserver = new ChatServer(8887); // Firefox does allow multible ssl connection only via port 443 //tested on FF16// load up the key storeString STORETYPE = "JKS";String KEYSTORE = Paths.get("src", "test", "java", "org", "java_websocket", "keystore.jks").toString();String STOREPASSWORD = "storepassword";String KEYPASSWORD = "keypassword";KeyStore ks = KeyStore.getInstance(STORETYPE);File kf = new File(KEYSTORE);ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, KEYPASSWORD.toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(ks);SSLContext sslContext = null;sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);chatserver.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext));chatserver.start();}} package com.test.test2;/** * Example for using the CustomSSLWebSocketServerFactory to allow just specific cipher suites */public class SSLServerCustomWebsocketFactoryExample {/** Keystore with certificate created like so (in JKS format):**keytool -genkey -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry"*/public static void main(String[] args) throws Exception {ChatServer chatserver = new ChatServer(8887); // Firefox does allow multible ssl connection only via port 443 //tested on FF16// load up the key storeString STORETYPE = "JKS";String KEYSTORE = Paths.get("src", "test", "java", "org", "java_websocket", "keystore.jks").toString();String STOREPASSWORD = "storepassword";String KEYPASSWORD = "keypassword";KeyStore ks = KeyStore.getInstance(STORETYPE);File kf = new File(KEYSTORE);ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, KEYPASSWORD.toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(ks);SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);//Lets remove some ciphers and protocolsSSLEngine engine = sslContext.createSSLEngine();List ciphers = new ArrayList(Arrays.asList(engine.getEnabledCipherSuites()));ciphers.remove("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");List protocols = new ArrayList(Arrays.asList(engine.getEnabledProtocols()));protocols.remove("SSLv3");CustomSSLWebSocketServerFactory factory = new CustomSSLWebSocketServerFactory(sslContext,protocols.toArray(new String[]{}), ciphers.toArray(new String[]{}));// Different example just using specific ciphers and protocols/*String[] enabledProtocols = {"TLSv1.2"};String[] enabledCipherSuites = {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA"};CustomSSLWebSocketServerFactory factory = new CustomSSLWebSocketServerFactory(sslContext, enabledProtocols,enabledCipherSuites);*/chatserver.setWebSocketFactory(factory);chatserver.start();}} package com.test.test2;/** * SSL Example using the LetsEncrypt certificate See #getting-a-sslcontext-using-a-lets-encrypt-certificate */public class SSLServerLetsEncryptExample {public static void main(String[] args) throws Exception {ChatServer chatserver = new ChatServer(8887);SSLContext context = getContext();if (context != null) {chatserver.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(getContext()));}chatserver.setConnectionLostTimeout(30);chatserver.start();}private static SSLContext getContext() {SSLContext context;String password = "CHANGEIT";String pathname = "pem";try {context = SSLContext.getInstance("TLS");byte[] certBytes = parseDERFromPEM(getBytes(new File(pathname + File.separator + "cert.pem")),"-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");byte[] keyBytes = parseDERFromPEM(getBytes(new File(pathname + File.separator + "privkey.pem")),"-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----");X509Certificate cert = generateCertificateFromDER(certBytes);RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes);KeyStore keystore = KeyStore.getInstance("JKS");keystore.load(null);keystore.setCertificateEntry("cert-alias", cert);keystore.setKeyEntry("key-alias", key, password.toCharArray(), new Certificate[]{cert});KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(keystore, password.toCharArray());KeyManager[] km = kmf.getKeyManagers();context.init(km, null, null);} catch (Exception e) {context = null;}return context;}private static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {String data = http://kandian.youth.cn/index/new String(pem);String[] tokens = data.split(beginDelimiter);tokens = tokens[1].split(endDelimiter);return DatatypeConverter.parseBase64Binary(tokens[0]);}private static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes)throws InvalidKeySpecException, NoSuchAlgorithmException {PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory factory = KeyFactory.getInstance("RSA");return (RSAPrivateKey) factory.generatePrivate(spec);}private static X509Certificate generateCertificateFromDER(byte[] certBytes)throws CertificateException {CertificateFactory factory = CertificateFactory.getInstance("X.509");return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));}private static byte[] getBytes(File file) {byte[] bytesArray = new byte[(int) file.length()];FileInputStream fis = null;try {fis = new FileInputStream(file);fis.read(bytesArray); //read file into bytes[]fis.close();} catch (IOException e) {e.printStackTrace();}return bytesArray;}} package com.test.test2;/** * Copy of SSLServerExample except we use @link SSLEngineWebSocketServerFactory to customize * clientMode/ClientAuth to force client to present a cert. Example of Two-way * ssl/MutualAuthentication/ClientAuthentication */public class TwoWaySSLServerExample {/** Keystore with certificate created like so (in JKS format):**keytool -genkey -keyalg RSA -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry"*/public static void main(String[] args) throws Exception {ChatServer chatserver = new ChatServer(8887); // Firefox does allow multible ssl connection only via port 443 //tested on FF16// load up the key storeString STORETYPE = "JKS";String KEYSTORE = Paths.get("src", "test", "java", "org", "java_websocket", "keystore.jks").toString();String STOREPASSWORD = "storepassword";String KEYPASSWORD = "keypassword";KeyStore ks = KeyStore.getInstance(STORETYPE);File kf = new File(KEYSTORE);ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, KEYPASSWORD.toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(ks);SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);SSLParameters sslParameters = new SSLParameters();// This is all we needsslParameters.setNeedClientAuth(true);chatserver.setWebSocketFactory(new SSLParametersWebSocketServerFactory(sslContext, sslParameters));chatserver.start();}}


推荐阅读