Netty SSL开发

 项目中难免会碰到需要开放通信接口给第三方调用。如果第三方模块在企业内网,通常不需要进行安全认证和SSL/TLS传输。可以利用IP黑白名单、握手登陆等方式进行安全认证,认证通过之后双方使用普通的Socket进行通信,认证失败,则拒绝客户端连接。 如果开放给企业外部第三方应用访问,则由于对服务调用者的监管存在诸多困难,或者无法有效监管,这些第三方应用实际是非授信的。为了有效应对安全风险,对于敏感的服务往往需要通过SSL/TLS进行安全传输。
    2014年上半年发现的Open SSL Heart Bleed漏洞,堪称网络安全里程碑事件,想必不少企业还心有余悸。
    JAVA开发中,引入SSL/TLS不麻烦。JDK的安全类库为我们提供了javax.net.ssl.SSLSocket和javax.net.ssl.SSLServerSocket,用于支持SSL/TLS安全传输,对于NIO非阻塞Socket通信,JDK并没有提供现成可用的类库简化用户开发,此时我们可以采用Netty。Netty通过JDK的SSLEngine,以SslHandler的方式提供对SSL/TLS安全传输的支持,极大的简化了用户的开发工作量,降低开发难度。
Get down to business,let's go!
   1.生成证书。请参考证书生成的相关帖子。
   2.在tcp链路初始化的时候,需要创建SSLContext并对其进行正确的初始化。server和client都有用到,make it as  a factory.
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public final class SecureChatSslContextFactory {
 
         private static final String PROTOCOL = "TLS" ;
         private static final SSLContext SERVER_CONTEXT;
         private static final SSLContext CLIENT_CONTEXT;
         private static final String KEYSTORE_FILE= "tomcat.jks" ;
         private static final String TRUSTSTORE_FILE= "tomcat.jks" ;
         private static final String KEYSTOREPASS= "1q2w3e4r5t" ;
         private static final String TRUSTSTOREPASS= "1q2w3e4r5t" ;
 
         static {
                 String algorithm = Security
                                 .getProperty( "ssl.KeyManagerFactory.algorithm" );
                 if (algorithm == null ) {
                         algorithm = "SunX509" ;
                 }
 
                 SSLContext serverContext;
                 SSLContext clientContext;
                 try {
                         KeyStore ks = KeyStore.getInstance( "JKS" );
                         ks.load( new ClassPathResource(KEYSTORE_FILE).getInputStream(),KEYSTOREPASS.toCharArray());
                         KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
                         kmf.init(ks, KEYSTOREPASS.toCharArray());
                         
                         KeyStore ts = KeyStore.getInstance( "JKS" );
             ts.load( new ClassPathResource(TRUSTSTORE_FILE).getInputStream(), TRUSTSTOREPASS.toCharArray());
             TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
             tmf.init(ts);
 
                         // Initialize the SSLContext to work with our key managers.
                         serverContext = SSLContext.getInstance(PROTOCOL);
                         serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null );
                 } catch (Exception e) {
                         throw new Error( "Failed to initialize the server-side SSLContext" ,
                                         e);
                 }
 
                 try {
                         KeyStore ks = KeyStore.getInstance( "JKS" );
                         ks.load( new ClassPathResource(KEYSTORE_FILE).getInputStream(),KEYSTOREPASS.toCharArray());
                         KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
                         kmf.init(ks, KEYSTOREPASS.toCharArray());
                         
                         ks = KeyStore.getInstance( "JKS" );
                         ks.load( new ClassPathResource(TRUSTSTORE_FILE).getInputStream(),TRUSTSTOREPASS.toCharArray());
                         TrustManagerFactory tmf=TrustManagerFactory.getInstance( "SunX509" );
                         tmf.init(ks);
                         
                         clientContext = SSLContext.getInstance(PROTOCOL);
                         clientContext.init(kmf.getKeyManagers(),tmf.getTrustManagers(), null );
                 } catch (Exception e) {
                         throw new Error( "Failed to initialize the client-side SSLContext" ,e);
                 }
 
                 SERVER_CONTEXT = serverContext;
                 CLIENT_CONTEXT = clientContext;
         }
 
         public static SSLContext getServerContext() {
                 return SERVER_CONTEXT;
         }
 
         public static SSLContext getClientContext() {
                 return CLIENT_CONTEXT;
         }
 
         private SecureChatSslContextFactory() {
                 // Unused
         }
}

3.服务端:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
bootstrap.setPipelineFactory( new ChannelPipelineFactory() {
 
    @Override
    public ChannelPipeline getPipeline() throws Exception {
     ChannelPipeline pipeline = Channels.pipeline();
     pipeline.addLast( "decoder" , new HttpRequestDecoder());
     pipeline.addLast( "encoder" , new HttpResponseEncoder());
     pipeline.addLast( "handler" , new AdminServerHandler());
     //for ssl
     SSLEngine engine=SecureChatSslContextFactory.getServerContext().createSSLEngine();
     engine.setUseClientMode( false );
     engine.setNeedClientAuth( false );
     pipeline.addFirst( "ssl" , new SslHandler(engine));
     return pipeline;
    }
   });
UseClientMode表示是否为客户端工作模式,我们这里是服务端,所以 engine.setUseClientMode(false);

NeedClientAuth表示是否需要对客户端验证,为false则为单向认证,true为双向认证。

4.客户端:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
bootstrap.setPipelineFactory( new ChannelPipelineFactory() {
  @Override
  public ChannelPipeline getPipeline() throws Exception {
   ChannelPipeline pipeline = Channels.pipeline();
   pipeline.addLast( "decoder" , new HttpResponseDecoder());
   pipeline.addLast( "encoder" , new HttpRequestEncoder());
   pipeline.addLast( "handler" , new ClientHandler());
   //for ssl
   SSLEngine engine=SecureChatSslContextFactory.getClientContext().createSSLEngine();
   engine.setUseClientMode( true );
   pipeline.addFirst( "ssl" , new SslHandler(engine));
   return pipeline;
  }
});
System.setProperty( "javax.net.debug" , "ssl,handshake" );

加上最后一行,是为了打开SSL握手的调测日志,查看SSL握手过程。

5.运行,日志如下:
[Shell]  纯文本查看  复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
***
found key for : localhost
chain [0] = [
[
Version: V3
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
Key: Sun RSA public key, 1024 bits
modulus: 134605017597439573459529369752834361953773187283155055519485401450040261606800534156496962689098461881800188488805056809511829247060448267316938812114273218710083404352418952490242035912859203687931674956266033686345718006660262091887376636473751699302295469516223778872513054644457510647330270185331624561871
public exponent: 65537
Validity: [From: Sat Aug 23 12:23:00 CST 2014,
To: Fri Aug 23 12:23:00 CST 2019]
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
SerialNumber: [ 08]
 
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality= false
BasicConstraints:[
CA: false
PathLen: undefined
]
 
]
Algorithm: [SHA1withRSA]
Signature:
0000: 0C F6 75 E7 D8 F5 9D 13 E5 B2 70 1E E4 A5 B4 9D ..u.......p.....
0010: C2 7E 78 B4 43 A6 5B DF 25 BA 95 68 42 86 6D 72 ..x.C.[.%..hB.mr
0020: 08 DE 73 96 1F 6F D9 C3 59 D3 8A 23 93 4D F3 84 ..s..o..Y.. #.M..
0030: 26 01 54 08 07 4B DF 47 FA 76 54 02 E7 73 18 40 &.T..K.G.vT..s.@
0040: 28 A0 4B 22 50 90 7F 9D 85 5B 26 18 55 1C AB 51 (.K"P....[&.U..Q
0050: B2 03 8E BA D1 B7 0D 33 75 61 E0 4D 80 03 3D 53 .......3ua.M..=S
0060: C3 DF FA 82 B1 9A 90 94 E3 F3 E3 D8 A0 2D 5E 91 .............-^.
0070: B1 67 91 E5 8B C2 DE AD 2E C2 F1 AD CC 9D 86 AF .g..............
0080: 52 42 C6 28 82 70 33 6B 28 A1 F5 23 8C 4D B2 F3 RB.(.p3k(.. #.M..
0090: 66 7B 69 57 73 22 34 D7 3C EF 4F E3 A4 27 4F DA f.iWs"4.<.O..'O.
00A0: 8B 5F 81 9B CA 62 73 73 84 EC C2 67 3E 3F 14 07 ._...bss...g>?..
00B0: CB 16 18 9D B4 78 F1 BE 5C A8 18 00 90 6D 61 6B .....x..\....mak
00C0: 25 66 5B 92 9E 17 B0 E0 32 01 08 47 C5 30 FF 0D %f[.....2..G.0..
00D0: 0B 11 D1 B4 EC 77 80 90 14 0D 7C D5 9B 06 36 7D .....w........6.
00E0: 0A 4C 11 5B AC E4 47 08 75 27 B8 E5 D5 18 82 AC .L.[..G.u'......
00F0: 49 CD D1 32 CD 47 A1 83 A4 50 86 CB 32 66 2E 04 I..2.G...P..2f..
 
]
***
adding as trusted cert:
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
Algorithm: RSA; Serial number: 0x8
Valid from Sat Aug 23 12:23:00 CST 2014 until Fri Aug 23 12:23:00 CST 2019
 
trigger seeding of SecureRandom
done seeding SecureRandom
***
found key for : localhost
chain [0] = [
[
Version: V3
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
Key: Sun RSA public key, 1024 bits
modulus: 134605017597439573459529369752834361953773187283155055519485401450040261606800534156496962689098461881800188488805056809511829247060448267316938812114273218710083404352418952490242035912859203687931674956266033686345718006660262091887376636473751699302295469516223778872513054644457510647330270185331624561871
public exponent: 65537
Validity: [From: Sat Aug 23 12:23:00 CST 2014,
To: Fri Aug 23 12:23:00 CST 2019]
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
SerialNumber: [ 08]
 
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality= false
BasicConstraints:[
CA: false
PathLen: undefined
]
 
]
Algorithm: [SHA1withRSA]
Signature:
0000: 0C F6 75 E7 D8 F5 9D 13 E5 B2 70 1E E4 A5 B4 9D ..u.......p.....
0010: C2 7E 78 B4 43 A6 5B DF 25 BA 95 68 42 86 6D 72 ..x.C.[.%..hB.mr
0020: 08 DE 73 96 1F 6F D9 C3 59 D3 8A 23 93 4D F3 84 ..s..o..Y.. #.M..
0030: 26 01 54 08 07 4B DF 47 FA 76 54 02 E7 73 18 40 &.T..K.G.vT..s.@
0040: 28 A0 4B 22 50 90 7F 9D 85 5B 26 18 55 1C AB 51 (.K"P....[&.U..Q
0050: B2 03 8E BA D1 B7 0D 33 75 61 E0 4D 80 03 3D 53 .......3ua.M..=S
0060: C3 DF FA 82 B1 9A 90 94 E3 F3 E3 D8 A0 2D 5E 91 .............-^.
0070: B1 67 91 E5 8B C2 DE AD 2E C2 F1 AD CC 9D 86 AF .g..............
0080: 52 42 C6 28 82 70 33 6B 28 A1 F5 23 8C 4D B2 F3 RB.(.p3k(.. #.M..
0090: 66 7B 69 57 73 22 34 D7 3C EF 4F E3 A4 27 4F DA f.iWs"4.<.O..'O.
00A0: 8B 5F 81 9B CA 62 73 73 84 EC C2 67 3E 3F 14 07 ._...bss...g>?..
00B0: CB 16 18 9D B4 78 F1 BE 5C A8 18 00 90 6D 61 6B .....x..\....mak
00C0: 25 66 5B 92 9E 17 B0 E0 32 01 08 47 C5 30 FF 0D %f[.....2..G.0..
00D0: 0B 11 D1 B4 EC 77 80 90 14 0D 7C D5 9B 06 36 7D .....w........6.
00E0: 0A 4C 11 5B AC E4 47 08 75 27 B8 E5 D5 18 82 AC .L.[..G.u'......
00F0: 49 CD D1 32 CD 47 A1 83 A4 50 86 CB 32 66 2E 04 I..2.G...P..2f..
 
]
***
adding as trusted cert:
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
Algorithm: RSA; Serial number: 0x8
Valid from Sat Aug 23 12:23:00 CST 2014 until Fri Aug 23 12:23:00 CST 2019
 
trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1404274080 bytes = { 20, 199, 59, 102, 154, 24, 236, 254, 112, 135, 229, 177, 227, 202, 166, 81, 80, 140, 135, 117, 112, 246, 199, 14, 73, 38, 159, 100 }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
New I /O worker #1, WRITE: TLSv1 Handshake, length = 73
New I /O worker #1, WRITE: SSLv2 client hello message, length = 98
New I /O worker #1, READ: TLSv1 Handshake, length = 769
*** ServerHello, TLSv1
RandomCookie: GMT: 1404274080 bytes = { 212, 81, 228, 50, 131, 116, 247, 192, 217, 218, 51, 52, 10, 120, 77, 39, 143, 66, 25, 102, 145, 206, 186, 69, 36, 254, 16, 181 }
Session ID: {84, 180, 134, 160, 85, 216, 73, 240, 207, 10, 248, 244, 91, 194, 67, 35, 62, 119, 72, 78, 210, 133, 203, 113, 155, 218, 144, 86, 154, 130, 68, 207}
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
Compression Method: 0
***
%% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
Key: Sun RSA public key, 1024 bits
modulus: 134605017597439573459529369752834361953773187283155055519485401450040261606800534156496962689098461881800188488805056809511829247060448267316938812114273218710083404352418952490242035912859203687931674956266033686345718006660262091887376636473751699302295469516223778872513054644457510647330270185331624561871
public exponent: 65537
Validity: [From: Sat Aug 23 12:23:00 CST 2014,
To: Fri Aug 23 12:23:00 CST 2019]
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
SerialNumber: [ 08]
 
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality= false
BasicConstraints:[
CA: false
PathLen: undefined
]
 
]
Algorithm: [SHA1withRSA]
Signature:
0000: 0C F6 75 E7 D8 F5 9D 13 E5 B2 70 1E E4 A5 B4 9D ..u.......p.....
0010: C2 7E 78 B4 43 A6 5B DF 25 BA 95 68 42 86 6D 72 ..x.C.[.%..hB.mr
0020: 08 DE 73 96 1F 6F D9 C3 59 D3 8A 23 93 4D F3 84 ..s..o..Y.. #.M..
0030: 26 01 54 08 07 4B DF 47 FA 76 54 02 E7 73 18 40 &.T..K.G.vT..s.@
0040: 28 A0 4B 22 50 90 7F 9D 85 5B 26 18 55 1C AB 51 (.K"P....[&.U..Q
0050: B2 03 8E BA D1 B7 0D 33 75 61 E0 4D 80 03 3D 53 .......3ua.M..=S
0060: C3 DF FA 82 B1 9A 90 94 E3 F3 E3 D8 A0 2D 5E 91 .............-^.
0070: B1 67 91 E5 8B C2 DE AD 2E C2 F1 AD CC 9D 86 AF .g..............
0080: 52 42 C6 28 82 70 33 6B 28 A1 F5 23 8C 4D B2 F3 RB.(.p3k(.. #.M..
0090: 66 7B 69 57 73 22 34 D7 3C EF 4F E3 A4 27 4F DA f.iWs"4.<.O..'O.
00A0: 8B 5F 81 9B CA 62 73 73 84 EC C2 67 3E 3F 14 07 ._...bss...g>?..
00B0: CB 16 18 9D B4 78 F1 BE 5C A8 18 00 90 6D 61 6B .....x..\....mak
00C0: 25 66 5B 92 9E 17 B0 E0 32 01 08 47 C5 30 FF 0D %f[.....2..G.0..
00D0: 0B 11 D1 B4 EC 77 80 90 14 0D 7C D5 9B 06 36 7D .....w........6.
00E0: 0A 4C 11 5B AC E4 47 08 75 27 B8 E5 D5 18 82 AC .L.[..G.u'......
00F0: 49 CD D1 32 CD 47 A1 83 A4 50 86 CB 32 66 2E 04 I..2.G...P..2f..
 
]
***
Found trusted certificate:
[
[
Version: V3
Subject: CN=localhost, OU=it, O=superv, ST=beijing, C=cn
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
Key: Sun RSA public key, 1024 bits
modulus: 134605017597439573459529369752834361953773187283155055519485401450040261606800534156496962689098461881800188488805056809511829247060448267316938812114273218710083404352418952490242035912859203687931674956266033686345718006660262091887376636473751699302295469516223778872513054644457510647330270185331624561871
public exponent: 65537
Validity: [From: Sat Aug 23 12:23:00 CST 2014,
To: Fri Aug 23 12:23:00 CST 2019]
Issuer: CN=customCA, OU=it, O=superv, ST=beijing, C=cn
SerialNumber: [ 08]
 
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality= false
BasicConstraints:[
CA: false
PathLen: undefined
]
 
]
Algorithm: [SHA1withRSA]
Signature:
0000: 0C F6 75 E7 D8 F5 9D 13 E5 B2 70 1E E4 A5 B4 9D ..u.......p.....
0010: C2 7E 78 B4 43 A6 5B DF 25 BA 95 68 42 86 6D 72 ..x.C.[.%..hB.mr
0020: 08 DE 73 96 1F 6F D9 C3 59 D3 8A 23 93 4D F3 84 ..s..o..Y.. #.M..
0030: 26 01 54 08 07 4B DF 47 FA 76 54 02 E7 73 18 40 &.T..K.G.vT..s.@
0040: 28 A0 4B 22 50 90 7F 9D 85 5B 26 18 55 1C AB 51 (.K"P....[&.U..Q
0050: B2 03 8E BA D1 B7 0D 33 75 61 E0 4D 80 03 3D 53 .......3ua.M..=S
0060: C3 DF FA 82 B1 9A 90 94 E3 F3 E3 D8 A0 2D 5E 91 .............-^.
0070: B1 67 91 E5 8B C2 DE AD 2E C2 F1 AD CC 9D 86 AF .g..............
0080: 52 42 C6 28 82 70 33 6B 28 A1 F5 23 8C 4D B2 F3 RB.(.p3k(.. #.M..
0090: 66 7B 69 57 73 22 34 D7 3C EF 4F E3 A4 27 4F DA f.iWs"4.<.O..'O.
00A0: 8B 5F 81 9B CA 62 73 73 84 EC C2 67 3E 3F 14 07 ._...bss...g>?..
00B0: CB 16 18 9D B4 78 F1 BE 5C A8 18 00 90 6D 61 6B .....x..\....mak
00C0: 25 66 5B 92 9E 17 B0 E0 32 01 08 47 C5 30 FF 0D %f[.....2..G.0..
00D0: 0B 11 D1 B4 EC 77 80 90 14 0D 7C D5 9B 06 36 7D .....w........6.
00E0: 0A 4C 11 5B AC E4 47 08 75 27 B8 E5 D5 18 82 AC .L.[..G.u'......
00F0: 49 CD D1 32 CD 47 A1 83 A4 50 86 CB 32 66 2E 04 I..2.G...P..2f..
 
]
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
New I /O worker #1, WRITE: TLSv1 Handshake, length = 134
SESSION KEYGEN:
PreMaster Secret:
0000: 03 01 57 6E A8 08 31 4B 44 65 98 D8 A2 1B BF 6A ..Wn..1KDe.....j
0010: 49 DC 46 34 0C 5B FE 2A AC 7F 40 45 CE 27 C5 25 I.F4.[.*..@E.'.%
0020: 48 48 14 5F CE 94 CA 39 A2 5E 24 A5 CD DE 48 06 HH._...9.^$...H.
CONNECTION KEYGEN:
Client Nonce:
0000: 54 B4 86 A0 14 C7 3B 66 9A 18 EC FE 70 87 E5 B1 T.....;f....p...
0010: E3 CA A6 51 50 8C 87 75 70 F6 C7 0E 49 26 9F 64 ...QP..up...I&.d
Server Nonce:
0000: 54 B4 86 A0 D4 51 E4 32 83 74 F7 C0 D9 DA 33 34 T....Q.2.t....34
0010: 0A 78 4D 27 8F 42 19 66 91 CE BA 45 24 FE 10 B5 .xM'.B.f...E$...
Master Secret:
0000: 4E 38 E0 8C 7F DB F4 F3 2E 79 5A 33 7B 29 63 C1 N8.......yZ3.)c.
0010: 70 AA 4B 10 AC 72 4A EB FC 23 A8 39 4B 5F FE EB p.K..rJ.. #.9K_..
0020: 56 D8 3A FA 8C D3 E6 63 FF 7A 7D 86 2E 1F 22 25 V.:....c.z...."%
Client MAC write Secret:
0000: 9D BD 43 12 9C 0E 63 E0 1F BF 22 A6 97 76 BF C8 ..C...c...".. v ..
Server MAC write Secret:
0000: D0 FC CE 89 17 82 E0 DF FB 8E 36 2A D4 F1 34 B4 ..........6*..4.
Client write key:
0000: 4D 67 6A 9A F4 FF C7 78 85 52 CC DC 7E 92 A4 C1 Mgj....x.R......
Server write key:
0000: 94 D2 56 C4 3B 24 87 FD 09 BC CA 1E B5 FD FE BA ..V.;$..........
... no IV used for this cipher
New I /O worker #1, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data: { 17, 247, 29, 50, 129, 174, 22, 57, 203, 198, 237, 115 }
***
New I /O worker #1, WRITE: TLSv1 Handshake, length = 32
New I /O worker #1, READ: TLSv1 Change Cipher Spec, length = 1
New I /O worker #1, READ: TLSv1 Handshake, length = 32
*** Finished
verify_data: { 75, 16, 13, 151, 225, 117, 242, 131, 205, 37, 186, 185 }
***
%% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
New I /O worker #1, WRITE: TLSv1 Application Data, length = 45
hello!! 你好
New I /O worker #1, READ: TLSv1 Alert, length = 18
New I /O worker #1, RECV TLSv1 ALERT: warning, close_notify
至此,大功告成。


Netty是一个基于Java NIO的网络通信框架,可以用于快速开发高性能的网络应用程序。WebSocket是一种在单个持久连接上进行全双工通信的协议,可以在客户端和服务器之间进行实时数据传输。而SSL(Secure Socket Layer)则是一种加密通信协议,用于确保网络通信的安全性。 在Netty中使用WebSocket进行通信时,可以通过SSL来加密通信,从而提高通信的安全性。在客户端中使用Netty WebSocket SSL,需要首先创建一个客户端的SSLContext,并加载对应的证书和密钥,然后将SSLContext集成到Netty的ChannelPipeline中。 在创建Netty的客户端时,首先需要创建一个Bootstrap实例,并配置相关的参数。然后,创建一个处理器(Handler),用于处理客户端的WebSocket请求和SSL加密。在处理器中,需要添加来自Netty的WebSocketClientProtocolHandler和SslHandler,用于处理WebSocket和SSL的握手和通信过程。 在向服务器发送WebSocket请求时,客户端需要构建一个WebSocket的握手请求,并将请求发送给服务器。在握手成功后,客户端就可以与服务器进行双向通信,通过WebSocket协议进行数据的传输。 总的来说,Netty WebSocket SSL客户端的实现需要首先创建SSLContext和配置客户端的Bootstrap实例,在处理器中将WebSocket和SSL的握手和通信进行集成,然后构建WebSocket的握手请求并与服务器进行通信,从而实现基于Netty的WebSocket SSL客户端的开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值