MINA, Netty, and Twisted: SSL/TLS, nettytls
What is SSL/TLS?
Network Communication without SSL/TLS is generally transmitted in plain text. The content transmitted over the network is easily eavesdropped or tampered with during transmission, which is extremely insecure. The SSL/TLS protocol is designed to solve these security problems. The SSL/TLS protocol is located above the TCP/IP protocol. Under each application layer protocol, the content transmitted over the network is encrypted using an encryption algorithm, and only the server and client can be encrypted and decrypted, even if packets are captured, the man-in-the-middle cannot decrypt the transmitted content to avoid security issues. For example, the widely used HTTPS protocol adds an SSL/TLS protocol between the TCP protocol and the HTTP protocol.
Related Terms
Before learning the SSL/TLS protocol, you must first understand some related concepts:
-Symmetric encryption: Both encryption and decryption use the same key. common algorithms include DES, 3DES, and AES, which are simpler and faster than asymmetric encryption algorithms.
-Asymmetric encryption: Unlike symmetric encryption algorithms, asymmetric encryption algorithms have two keys: Public Key (Public Key) and private key (Private Key). For example, if the client uses public key encryption, in this case, other people cannot decrypt their public keys. They can only decrypt them using the private key of the server. The RSA algorithm is a typical asymmetric encryption algorithm.
-Digital Certificate: a digital certificate is a string of data that contains a public key and is issued by an authority. Many digital certificates are free of charge and need to be paid. You can also generate a digital certificate by yourself, this document will generate a digital certificate using a self-signed method.
SSL/TLS Process
Before the server and client that use the SSL/TLS Protocol begin to communicate, a handshake phase is performed:
After the handshake, the client and server both have three random numbers in the handshake phase. Both the client and the server generate a random key through these three keys. Then, all the communication content uses this key to encrypt the transmission through the symmetric encryption algorithm, and the server and the client start secure communication.
If you can see that it is still awesome, you can refer to the overview of the SSL/TLS Protocol operating mechanism to learn more about the SSL/TLS process. This article will not introduce it too much.
Generate private key and Certificate
Use openssl to generate the private key and certificate:
openssl req -x509 -newkey rsa:2048 -nodes -days 365 -keyout private.pem -out cert.crt
After running the preceding command, a private key file (private. pem) and a certificate file (cert. crt) are generated in the current directory ).
The generated private key and certificate Twisted and Netty can be used directly. However, MINA needs to convert the pem format to der format for the private key file format, the private key of a text file is actually converted into a binary file private key. Openssl converts private. pem to a private. der private key file:
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform DER -nocrypt -out private.der
SSL/TLS server
Next.
MINA
MINA can use SslFilter to implement SSL/TLS. The code for initializing SslFilter is cumbersome:
Public class MinaServer {public static void main (String [] args) throws Exception {String certPath = "/Users/wucao/Desktop/ssl/cert. crt "; // certificate String privateKeyPath ="/Users/wucao/Desktop/ssl/private. der "; // Private Key // Certificate // https://docs.oracle.com/javase/7/docs/api/java/security/cert/X509Certificate.html InputStream inStream = null; certificate Certificate = null; try {inStream = new FileInputStre Am (certPath); CertificateFactory cf = CertificateFactory. getInstance ("X.509"); certificate = cf. generateCertificate (inStream);} finally {if (inStream! = Null) {inStream. close () ;}// Private Key PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (Files. readAllBytes (new File (privateKeyPath ). toPath (); PrivateKey privateKey = KeyFactory. getInstance ("RSA "). generatePrivate (keySpec); KeyStore ks = KeyStore. getInstance (KeyStore. getDefaultType (); ks. load (null, null); Certificate [] certificates = {certificate}; ks. setKeyEntry ("key", privateKey ,"". toCharArray (), certificates); KeyManagerFactory kmf = KeyManagerFactory. getInstance (KeyManagerFactory. getDefaultAlgorithm (); kmf. init (ks ,"". toCharArray (); SSLContext sslContext = SSLContext. getInstance ("TLS"); sslContext. init (kmf. getKeyManagers (), null, null); IoAcceptor acceptor = new NioSocketAcceptor (); DefaultIoFilterChainBuilder chain = acceptor. getFilterChain (); chain. addLast ("ssl", new SslFilter (sslContext); // SslFilter needs to be placed at the beginning of chain. addLast ("codec", new ProtocolCodecFilter (new TextLineCodecFactory (Charset. forName ("UTF-8"), "\ r \ n", "\ r \ n"); acceptor. setHandler (new TcpServerHandle (); acceptor. bind (new InetSocketAddress (8080);} class TcpServerHandle extends IoHandlerAdapter {@ Override public void exceptionCaught (IoSession session, Throwable cause) throws Exception {cause. printStackTrace () ;}@ Override public void messageReceived (IoSession session, Object message) throws Exception {String line = (String) message; System. out. println ("messageReceived:" + line) ;}@ Override public void sessionCreated (IoSession session) throws Exception {System. out. println ("sessionCreated") ;}@ Override public void sessionClosed (IoSession session) throws Exception {System. out. println ("sessionClosed ");}}
Netty
Netty implements SSL/TLS by adding an SslHandler, Which is simpler than MINA:
Public class NettyServer {public static void main (String [] args) throws InterruptedException, SSLException {File certificate = new File ("/Users/wucao/Desktop/ssl/cert. crt "); // Certificate File privateKey = new File ("/Users/wucao/Desktop/ssl/private. pem "); // Private Key final SslContext sslContext = SslContextBuilder. forServer (certificate, privateKey ). build (); EventLoopGroup bossGroup = new NioEventLoopGroup (); EventLoopGroup workerGroup = new NioEventLoopGroup (); try {ServerBootstrap B = new ServerBootstrap (); B. group (bossGroup, workerGroup ). channel (NioServerSocketChannel. class ). childHandler (new ChannelInitializer <SocketChannel> () {@ Override public void initChannel (SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch. pipeline (); // The SslHandler must be placed at the beginning of SslHandler sslHandler = sslContext. newHandler (ch. alloc (); pipeline. addLast (sslHandler); pipeline. addLast (new LineBasedFrameDecoder (80); pipeline. addLast (new StringDecoder (CharsetUtil. UTF_8); pipeline. addLast (new TcpServerHandler () ;}}); ChannelFuture f = B. bind (8080 ). sync (); f. channel (). closeFuture (). sync ();} finally {workerGroup. shutdownGracefully (); bossGroup. shutdownGracefully () ;}} class TcpServerHandler extends ChannelInboundHandlerAdapter {@ Override public void channelRead (ChannelHandlerContext ctx, Object msg) {String line = (String) msg; System. out. println ("channelRead:" + line) ;}@ Override public void channelActive (ChannelHandlerContext ctx) {System. out. println ("channelActive") ;}@ Override public void channelInactive (ChannelHandlerContext ctx) {System. out. println ("channelInactive") ;}@ Override public void exceptionCaught (ChannelHandlerContext ctx, Throwable cause) {cause. printStackTrace (); ctx. close ();}}
Twisted
Twisted is easy to implement SSL/TLS. Replace reactor. listenTCP with reactor. listenSSL.
#-*-Coding: UTF-8-*-from twisted. protocols. basic import LineOnlyReceiverfrom twisted. internet. protocol import Factoryfrom twisted. internet import reactor, sslsslContext = ssl. defaultOpenSSLContextFactory ('/Users/wucao/Desktop/ssl/private. pem', # Private Key '/Users/wucao/Desktop/ssl/cert. crt ', # Public Key) class TcpServerHandle (LineOnlyReceiver): def connectionMade (self): print 'ononmade' def connectionLost (self, reason): print 'ononlost' def lineReceived (self, data): print 'linereceived: '+ datafactory = Factory () factory. protocol = TcpServerHandlereactor. listenSSL (8080, factory, sslContext) reactor. run ()
SSL/TLS client
Here we still use Java to write an SSL/TLS client to test the above three server programs. Note that, in the SSL/TLS process described above, the server in step 1 of the SSL/TLS handshake phase will send the certificate to the client, and the client in step 2 will verify the validity of the certificate, therefore, the following code first allows the client to trust the certificate generated by openssl before the SSL/TLS handshake can be completed correctly.
Public class SSLClient {public static void main (String args []) throws Exception {// change the client trust certificate, check the validity of the certificate sent from the server. String certPath = "/Users/wucao/Desktop/ssl/cert. crt "; InputStream inStream = null; Certificate certificate = null; try {inStream = new FileInputStream (certPath); CertificateFactory cf = CertificateFactory. getInstance ("X.509"); certificate = cf. generateCertificate (inStream);} finally {If (inStream! = Null) {inStream. close () ;}} KeyStore ks = KeyStore. getInstance (KeyStore. getDefaultType (); ks. load (null, null); ks. setCertificateEntry ("cert", certificate); TrustManagerFactory tmf = TrustManagerFactory. getInstance ("sunx509"); tmf. init (ks); SSLContext sslContext = SSLContext. getInstance ("TLS"); sslContext. init (null, tmf. getTrustManagers (), null); SSLSocketFactory socketFactory = sslContext. getSocketFactory (); Socket socket = null; OutputStream out = null; try {socket = socketFactory. createSocket ("localhost", 8080); out = socket. getOutputStream (); // request the Server String lines = "Moonlight \ r \ n in front of the bed suspected to be frost on the ground \ r \ n raised his head and looked at the moon \ r \ n bowed his head to his hometown \ r \ n "; byte [] outputBytes = lines. getBytes ("UTF-8"); out. write (outputBytes); out. flush ();} finally {// close the connection out. close (); socket. close ();}}}
MINA, Netty, and Twisted
MINA, Netty, and Twisted: A simple TCP Server
MINA, Netty, and Twisted: TCP Message boundary and line-based message splitting
MINA, Netty, and Twisted (3): Fixed TCP Message prefix (Header)
MINA, Netty, and Twisted (4): Customize your own protocol
MINA, Netty, and Twisted: integration with protobuf
MINA, Netty, and Twisted (6): session
MINA, Netty, and Twisted (7): Publish/Subscribe (Publish/Subscribe)
MINA, Netty, and Twisted: HTTP Server
MINA, Netty, and Twisted: asynchronous IO and callback Functions
MINA, Netty, and Twisted: thread model
MINA, Netty, and Twisted: SSL/TLS
Source code
Https://github.com/wucao/mina-netty-twisted