【问题标题】:Netty SslHandler headacheNetty SslHandler 头疼
【发布时间】:2012-06-22 09:04:56
【问题描述】:

我现在已经浪费了几天时间来寻找新添加的 Akka 传输加密中的一个间歇性错误。

注意:我已经尝试在服务器和客户端中的一个或两个上设置 setIssueHandshake(true),但它根本没有帮助。

我们的密码规范测试了来自不同套件的几个不同密码,以确保我们支持的设置确实有效。但是,测试有时可以通过 10 次,然后开始在所有其他测试中失败,这确实是 SecureRandomly 失败 ;-) 请注意,即使在 SHA1PRNG 上测试也会失败,因此它显然与我们提供的其他密码无关。

创建 SslHandler 的代码:https://github.com/akka/akka/blob/wip-ssl-unbroken-%E2%88%9A/akka-remote/src/main/scala/akka/remote/netty/NettySSLSupport.scala

构造管道的代码:https://github.com/akka/akka/blob/wip-ssl-unbroken-%E2%88%9A/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala#L66

测试:https://github.com/akka/akka/blob/wip-ssl-unbroken-%E2%88%9A/akka-remote/src/test/scala/akka/remote/Ticket1978CommunicationSpec.scala

后备配置(上面的测试没有覆盖):https://github.com/akka/akka/blob/wip-ssl-unbroken-%E2%88%9A/akka-remote/src/main/resources/reference.conf

用于测试的密钥库和信任库:https://github.com/akka/akka/tree/wip-ssl-unbroken-%E2%88%9A/akka-remote/src/test/resources

测试失败的根异常是:

**java.security.InvalidKeyException: No installed provider supports this key: (null)**
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at com.sun.net.ssl.internal.ssl.CipherBox.<init>(CipherBox.java:88)
    at com.sun.net.ssl.internal.ssl.CipherBox.newCipherBox(CipherBox.java:119)
    at com.sun.net.ssl.internal.ssl.CipherSuite$BulkCipher.newCipher(CipherSuite.java:369)
    at com.sun.net.ssl.internal.ssl.Handshaker.newReadCipher(Handshaker.java:410)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.changeReadCiphers(SSLEngineImpl.java:550)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1051)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:845)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:721)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607)
    at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:969)
    at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:670)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:333)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:91)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:373)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:247)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

而“完整”的是:

[ERROR] [06/20/2012 10:38:33.670] [remote-sys-4] [ActorSystem(remote-sys)] RemoteServerError@akka://remote-sys@localhost:59104] Error[
javax.net.ssl.SSLException: Algorithm missing:  
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.changeReadCiphers(SSLEngineImpl.java:554)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1051)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:845)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:721)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607)
    at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:969)
    at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:670)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:333)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:91)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:373)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:247)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.security.NoSuchAlgorithmException: Could not create cipher AES/128
    at com.sun.net.ssl.internal.ssl.CipherBox.<init>(CipherBox.java:99)
    at com.sun.net.ssl.internal.ssl.CipherBox.newCipherBox(CipherBox.java:119)
    at com.sun.net.ssl.internal.ssl.CipherSuite$BulkCipher.newCipher(CipherSuite.java:369)
    at com.sun.net.ssl.internal.ssl.Handshaker.newReadCipher(Handshaker.java:410)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.changeReadCiphers(SSLEngineImpl.java:550)
    ... 17 more
Caused by: java.security.InvalidKeyException: No installed provider supports this key: (null)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at com.sun.net.ssl.internal.ssl.CipherBox.<init>(CipherBox.java:88)
    ... 21 more
]

【问题讨论】:

    标签: scala netty


    【解决方案1】:

    虽然我没有确切地看到这个异常,但javax.crypto.Cipher 肯定不是线程安全的;我有一个应用程序,我终于找到了一个通过同步密码解决的错误:

    cipher synchronized { cipher doFinal encryptedBytes }
    

    抱歉,如果这不是解决方案,但您发布了很多代码! (这可能与堆栈跟踪表明问题甚至出现Cipher 实例并不完全相同——但这是否也需要同步?)

    【讨论】:

      【解决方案2】:

      不是 Netty 中的错误,不幸的是,在应用程序级握手和 SSL 握手之间存在写入竞争。值得注意的是 setIssueHandshake(true) 似乎并没有透明地处理握手,因为您需要手动退出写入直到握手完成。

      【讨论】:

      • 我认为这已在 netty 3.5.0.Final.. 你使用的是什么版本?
      • 能否请您打开一个错误,以便我们在 3.5.1Final 之前修复它?
      • setIssueHandshake 的错误?因为除此之外,我当然需要等待握手 Future 完成,然后再发出应用程序级握手。
      • 是的,我想知道我们是否应该在握手完成之前将消息排队。另一方面,我们可以从 javadocs 中更清楚地了解它是如何工作的。
      • 直觉上我会说它应该在让任何消息通过之前建立握手。不然有什么意义呢?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      • 2020-07-13
      • 2014-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多