为什么要使用SSLEngine, 参考javadoc的说明:
SSLSocket
类提供很多相同的安全功能,但是所有的入站和出站数据都是使用底层 Socket
自动地传输,底层 Socket 设计为使用阻塞模型。虽然这适合于很多应用程序,但是此模型却不提供大型服务器所需的可伸缩性。
SSLEngine
的主要特征是它在入站和出站的字节流上操作,与传输机制无关。安排到同位体可靠的 I/O 传输是 SSLEngine
用户的职责。通过从 I/O 传输机制中分离出 SSL/TLS 抽象,SSLEngine
可以被用于各种 I/O 类型,例如 non-blocking I/O (polling)
、selectable non-blocking I/O
、 Socket
和传统的 Input/OutputStreams、本地的 ByteBuffers
或字节数组、未来的异步 I/O 模型等等。
怎么使用SSLEngine, 示例源代码位置:
http://www.cs.lafayette.edu/docs/java/guide/security/jsse/samples/
/* * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Oracle nor the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */ /** * A SSLEngine usage example which simplifies the presentation * by removing the I/O and multi-threading concerns. * * The demo creates two SSLEngines, simulating a client and server. * The "transport" layer consists two ByteBuffers: think of them * as directly connected pipes. * * Note, this is a *very* simple example: real code will be much more * involved. For example, different threading and I/O models could be * used, transport mechanisms could close unexpectedly, and so on. * * When this application runs, notice that several messages * (wrap/unwrap) pass before any application data is consumed or * produced. (For more information, please see the SSL/TLS * specifications.) There may several steps for a successful handshake, * so it's typical to see the following series of operations: * * client server message * ====== ====== ======= * wrap() ... ClientHello * ... unwrap() ClientHello * ... wrap() ServerHello/Certificate * unwrap() ... ServerHello/Certificate * wrap() ... ClientKeyExchange * wrap() ... ChangeCipherSpec * wrap() ... Finished * ... unwrap() ClientKeyExchange * ... unwrap() ChangeCipherSpec * ... unwrap() Finished * ... wrap() ChangeCipherSpec * ... wrap() Finished * unwrap() ... ChangeCipherSpec * unwrap() ... Finished */ import javax.net.ssl.*; import javax.net.ssl.SSLEngineResult.*; import java.io.*; import java.security.*; import java.nio.*; public class SSLEngineSimpleDemo { /* * Enables logging of the SSLEngine operations. */ private static boolean logging = true; /* * Enables the JSSE system debugging system property: * * -Djavax.net.debug=all * * This gives a lot of low-level information about operations underway, * including specific handshake messages, and might be best examined after * gaining some familiarity with this application. */ private static boolean debug = false; private SSLContext sslc; private SSLEngine clientEngine; // client Engine private ByteBuffer clientOut; // write side of clientEngine private ByteBuffer clientIn; // read side of clientEngine private SSLEngine serverEngine; // server Engine private ByteBuffer serverOut; // write side of serverEngine private ByteBuffer serverIn; // read side of serverEngine /* * For data transport, this example uses local ByteBuffers. This isn't * really useful, but the purpose of this example is to show SSLEngine * concepts, not how to do network transport. */ private ByteBuffer cTOs; // "reliable" transport client->server private ByteBuffer sTOc; // "reliable" transport server->client /* * The following is to set up the keystores. */ private static String keyStoreFile = "testkeys"; private static String trustStoreFile = "testkeys"; private static String passwd = "passphrase"; /* * Main entry point for this demo. */ public static void main(String args[]) throws Exception { if (debug) { System.setProperty("javax.net.debug", "all"); } SSLEngineSimpleDemo demo = new SSLEngineSimpleDemo(); demo.runDemo(); System.out.println("Demo Completed."); } /* * Create an initialized SSLContext to use for this demo. */ public SSLEngineSimpleDemo() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); KeyStore ts = KeyStore.getInstance("JKS"); char[] passphrase = "passphrase".toCharArray(); ks.load(new FileInputStream(keyStoreFile), passphrase); ts.load(new FileInputStream(trustStoreFile), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ts); SSLContext sslCtx = SSLContext.getInstance("TLS"); sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); sslc = sslCtx; } /* * Run the demo. * * Sit in a tight loop, both engines calling wrap/unwrap regardless of * whether data is available or not. We do this until both engines report * back they are closed. * * The main loop handles all of the I/O phases of the SSLEngine's lifetime: * * initial handshaking application data transfer engine closing * * One could easily separate these phases into separate sections of code. */ private void runDemo() throws Exception { boolean dataDone = false; createSSLEngines(); createBuffers(); SSLEngineResult clientResult; // results from client's last operation SSLEngineResult serverResult; // results from server's last operation /* * Examining the SSLEngineResults could be much more involved, and may * alter the overall flow of the application. * * For example, if we received a BUFFER_OVERFLOW when trying to write to * the output pipe, we could reallocate a larger pipe, but instead we * wait for the peer to drain it. */ while (!isEngineClosed(clientEngine) || !isEngineClosed(serverEngine)) { log("================"); clientResult = clientEngine.wrap(clientOut, cTOs); log("client wrap: ", clientResult); runDelegatedTasks(clientResult, clientEngine); serverResult = serverEngine.wrap(serverOut, sTOc); log("server wrap: ", serverResult); runDelegatedTasks(serverResult, serverEngine); cTOs.flip(); sTOc.flip(); log("----"); clientResult = clientEngine.unwrap(sTOc, clientIn); log("client unwrap: ", clientResult); runDelegatedTasks(clientResult, clientEngine); serverResult = serverEngine.unwrap(cTOs, serverIn); log("server unwrap: ", serverResult); runDelegatedTasks(serverResult, serverEngine); cTOs.compact(); sTOc.compact(); /* * After we've transfered all application data between the client * and server, we close the clientEngine's outbound stream. This * generates a close_notify handshake message, which the server * engine receives and responds by closing itself. * * In normal operation, each SSLEngine should call closeOutbound(). * To protect against truncation attacks, SSLEngine.closeInbound() * should be called whenever it has determined that no more input * data will ever be available (say a closed input stream). */ if (!dataDone && (clientOut.limit() == serverIn.position()) && (serverOut.limit() == clientIn.position())) { /* * A sanity check to ensure we got what was sent. */ checkTransfer(serverOut, clientIn); checkTransfer(clientOut, serverIn); log("\tClosing clientEngine's *OUTBOUND*..."); clientEngine.closeOutbound(); // serverEngine.closeOutbound(); dataDone = true; } } } /* * Using the SSLContext created during object creation, create/configure the * SSLEngines we'll use for this demo. */ private void createSSLEngines() throws Exception { /* * Configure the serverEngine to act as a server in the SSL/TLS * handshake. Also, require SSL client authentication. */ serverEngine = sslc.createSSLEngine(); serverEngine.setUseClientMode(false); serverEngine.setNeedClientAuth(true); /* * Similar to above, but using client mode instead. */ clientEngine = sslc.createSSLEngine("client", 80); clientEngine.setUseClientMode(true); } /* * Create and size the buffers appropriately. */ private void createBuffers() { /* * We'll assume the buffer sizes are the same between client and server. */ SSLSession session = clientEngine.getSession(); int appBufferMax = session.getApplicationBufferSize(); int netBufferMax = session.getPacketBufferSize(); /* * We'll make the input buffers a bit bigger than the max needed size, * so that unwrap()s following a successful data transfer won't generate * BUFFER_OVERFLOWS. * * We'll use a mix of direct and indirect ByteBuffers for tutorial * purposes only. In reality, only use direct ByteBuffers when they give * a clear performance enhancement. */ clientIn = ByteBuffer.allocate(appBufferMax + 50); serverIn = ByteBuffer.allocate(appBufferMax + 50); cTOs = ByteBuffer.allocateDirect(netBufferMax); sTOc = ByteBuffer.allocateDirect(netBufferMax); clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes()); serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes()); } /* * If the result indicates that we have outstanding tasks to do, go ahead * and run them in this thread. */ private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) throws Exception { if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { Runnable runnable; while ((runnable = engine.getDelegatedTask()) != null) { log("\trunning delegated task..."); runnable.run(); } HandshakeStatus hsStatus = engine.getHandshakeStatus(); if (hsStatus == HandshakeStatus.NEED_TASK) { throw new Exception("handshake shouldn't need additional tasks"); } log("\tnew HandshakeStatus: " + hsStatus); } } private static boolean isEngineClosed(SSLEngine engine) { return (engine.isOutboundDone() && engine.isInboundDone()); } /* * Simple check to make sure everything came across as expected. */ private static void checkTransfer(ByteBuffer a, ByteBuffer b) throws Exception { a.flip(); b.flip(); if (!a.equals(b)) { throw new Exception("Data didn't transfer cleanly"); } else { log("\tData transferred cleanly"); } a.position(a.limit()); b.position(b.limit()); a.limit(a.capacity()); b.limit(b.capacity()); } /* * Logging code */ private static boolean resultOnce = true; private static void log(String str, SSLEngineResult result) { if (!logging) { return; } if (resultOnce) { resultOnce = false; System.out.println("The format of the SSLEngineResult is: \n" + "\t\"getStatus() / getHandshakeStatus()\" +\n" + "\t\"bytesConsumed() / bytesProduced()\"\n"); } HandshakeStatus hsStatus = result.getHandshakeStatus(); log(str + result.getStatus() + "/" + hsStatus + ", " + result.bytesConsumed() + "/" + result.bytesProduced() + " bytes"); if (hsStatus == HandshakeStatus.FINISHED) { log("\t...ready for application data"); } } private static void log(String str) { if (logging) { System.out.println(str); } } }
相关推荐
3. 创建SSLEngine:SSLContext的createSSLEngine方法用于创建SSLEngine对象,它是实际处理加密和解密的组件。 4. 设置SSLEngine属性:如需要进行双向身份验证(mutual SSL),需要开启需要客户端认证的属性。 5. ...
2. **创建SSLEngine**:然后,使用SSLContext创建一个SSLEngine实例,它是实际处理SSL/TLS连接的对象。SSLEngine可以应用于非阻塞IO模型,适合Netty的NIO(非阻塞I/O)架构。 3. **自定义ChannelInitializer**:在...
本示例"sslJAVA_example"将介绍如何在Java环境中实现SSL连接。 1. **SSL的基本原理** SSL通过使用公钥和私钥的非对称加密以及共享密钥的对称加密来保证数据的安全。在建立连接时,服务器会提供数字证书,包含其...
在`www.pudn.com.txt`和`Java_SSL`这两个文件中,可能包含了更详细的代码示例和步骤说明。阅读这些文件可以帮助你更好地理解如何在Java中实现SSL加密以及如何使用OpenSSL生成必要的密钥和证书。 总的来说,Java中的...
SSLEngine on SSLCertificateFile /path/to/server.crt SSLCertificateKeyFile /path/to/server.key ``` #### 五、测试和验证SSL配置 1. **重启Apache服务**:确保新的配置生效。 - 命令示例:`service ...
4. **启动HTTPS服务器**:使用SSLContext创建SSLEngine,并将其应用到ServerSocket上,然后监听并处理客户端连接。 在`Server.java`这个文件中,可能会包含上述步骤的代码实现,例如创建一个`...
**Tomcat 配置示例** 在使用 Tomcat 这样的服务器软件时,你可能需要在服务器配置文件(如 `server.xml`)中指定 SSL 相关设置。这通常包括启用 SSL、指定 keystore 文件路径、密码等。例如: ```xml SSLEnabled...
以下是一段创建SSLFilter并添加到过滤器链的基本代码示例: ```java SslFilter sslFilter = new SslFilter(sslContext); sslFilter.setUseClientMode(false); // 设置为服务器模式 filterChain.addFirst("sslFilter...
SSLEngine on SSLCertificateFile /path/to/server.crt SSLCertificateKeyFile /path/to/server.key ... ``` 在 Nginx 中,相应的配置位于 `nginx.conf` 或每个 server 块中: ```nginx server { listen 443...
4. **SSLSocket/SSLEngine**:实际执行加密的网络连接,SSLSocket用于阻塞I/O,SSLEngine则支持非阻塞I/O。 **定制SSL主要涉及以下方面:** 1. **自定义密钥和证书**:你可以生成自己的数字证书和私钥,通过...
在Android平台上,SSL(Secure Sockets Layer)与TLS(Transport Layer Security)协议是用于实现安全网络通信的关键技术。...通过这个示例,开发者可以更好地理解和掌握如何在移动设备上实现安全且高效的网络连接。
SSLEngine on SSLCertificateFile /etc/pki/tls/certs/server.crt SSLCertificateKeyFile /etc/pki/tls/private/server.key ``` 2. **限制访问** - 通过`Require`指令控制访问权限。 - 示例配置: ```...
代码中可能包括了如`SSLEngine`的创建和配置,证书的加载,以及异常处理等关键部分。通过学习这个示例,你将能够更好地理解和应用Netty的安全通信机制,这对于开发涉及敏感数据传输的应用至关重要。
在示例中,`.downcc.com`的DNS解析结果显示其IP地址为`192.168.2.115`。这是客户端通过互联网找到服务器的第一步。 接着,为了启用HTTPS,必须安装Apache的SSL支持模块。在大多数Linux系统中,可以使用`yum install...
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> ``` ##### 3.3 GlobalNamingResources元素 - **描述**:`<GlobalNamingResources>`元素用于配置全局JNDI资源。 - **...
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> ... Apache 集成 Tomcat 代理配置可以实现高可用性和高性能的 Web 应用程序。通过配置 httpd....
一个简单的用法示例:它将接收到的二进制消息以十六进制形式打印到控制台,并回显文本消息: client = new WebSocketClient("wss://localhost:9999/") { @Override public void onTextReceived(String text
- `AprLifecycleListener`:加载 APR 库以提高性能,通过 `SSLEngine` 属性启用 SSL 加速。 - `JreMemoryLeakPreventionListener`:防止 Java 运行时 API 引起的内存泄漏。 - `GlobalResourcesLifecycleListener`...
SSLEngine on SSLCertificateFile "/usr/local/httpd/conf/server.crt" SSLCertificateKeyFile "/usr/local/httpd/conf/server.key" # 其他SSL配置项 ``` **5. 启用HTTPS并配置重定向** 为了让用户在访问HTTP...