我有一个akka-streams拓扑,我使用akka-http进行POST调用。
在将请求发送到不安全的服务器(具有自签名证书)时,我遇到以下错误。它是一个内部服务器,所以从安全的角度来看我很好。
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478) ~[?:1.8.0_131]
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535) ~[?:1.8.0_131]
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:813) ~[?:1.8.0_131]
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781) ~[?:1.8.0_131]
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[?:1.8.0_131]
at akka.stream.impl.io.TLSActor.akka$stream$impl$io$TLSActor$$doUnwrap(TLSActor.scala:367) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor.akka$stream$impl$io$TLSActor$$doInbound(TLSActor.scala:290) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor$$anonfun$1.apply$mcV$sp(TLSActor.scala:225) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.Pump$class.pump(Transfer.scala:199) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor.pump(TLSActor.scala:48) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.BatchingInputBuffer.enqueueInputElement(ActorProcessor.scala:90) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.BatchingInputBuffer$$anonfun$upstreamRunning$1.applyOrElse(ActorProcessor.scala:141) ~[akka-stream_2.11-2.4.17.jar:?]
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) ~[scala-library-2.11.8.jar:?]
at akka.stream.impl.SubReceive.apply(Transfer.scala:16) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.FanIn$InputBunch$$anonfun$subreceive$1.applyOrElse(FanIn.scala:234) ~[akka-stream_2.11-2.4.17.jar:?]
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) ~[scala-library-2.11.8.jar:?]
at akka.stream.impl.SubReceive.apply(Transfer.scala:16) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.SubReceive.apply(Transfer.scala:12) ~[akka-stream_2.11-2.4.17.jar:?]
at scala.PartialFunction$class.applyOrElse(PartialFunction.scala:123) ~[scala-library-2.11.8.jar:?]
at akka.stream.impl.SubReceive.applyOrElse(Transfer.scala:12) ~[akka-stream_2.11-2.4.17.jar:?]
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:170) ~[scala-library-2.11.8.jar:?]
at akka.actor.Actor$class.aroundReceive(Actor.scala:497) ~[akka-actor_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor.aroundReceive(TLSActor.scala:48) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526) ~[akka-actor_2.11-2.4.17.jar:?]
at akka.actor.ActorCell.invoke(ActorCell.scala:495) ~[akka-actor_2.11-2.4.17.jar:?]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257) ~[akka-actor_2.11-2.4.17.jar:?]
at akka.dispatch.Mailbox.run(Mailbox.scala:224) ~[akka-actor_2.11-2.4.17.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_131]
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[?:1.8.0_131]
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) ~[?:1.8.0_131]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) ~[?:1.8.0_131]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:966) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:963) ~[?:1.8.0_131]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416) ~[?:1.8.0_131]
at akka.stream.impl.io.TLSActor.runDelegatedTasks(TLSActor.scala:402) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor.akka$stream$impl$io$TLSActor$$doUnwrap(TLSActor.scala:371) ~[akka-stream_2.11-2.4.17.jar:?]
... 24 more
Caused by: java.security.cert.CertificateException: No subject alternative names present
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:144) ~[?:1.8.0_131]
at sun.security.util.HostnameChecker.match(HostnameChecker.java:93) ~[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) ~[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436) ~[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252) ~[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136) ~[?:1.8.0_131]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1501) ~[?:1.8.0_131]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:966) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:963) ~[?:1.8.0_131]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_131]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416) ~[?:1.8.0_131]
at akka.stream.impl.io.TLSActor.runDelegatedTasks(TLSActor.scala:402) ~[akka-stream_2.11-2.4.17.jar:?]
at akka.stream.impl.io.TLSActor.akka$stream$impl$io$TLSActor$$doUnwrap(TLSActor.scala:371) ~[akka-stream_2.11-2.4.17.jar:?]
一些讨论发生了here,另一个解决方案here和here,但对我和一个未完成的讨论here没有用。提出了一个解决方案here,但不确定如何为akka-http实现相同的解决方案。 几个相关的链接:
之前我只是使用以下来执行它:
Http().superPool[MyTracker]()
我也尝试过关注,从here和here获取灵感,但问题仍然存在:
val badSslConfig = AkkaSSLConfig().mapSettings(s => s.withLoose(s.loose.withAcceptAnyCertificate(true)))
val badCtx = Http().createClientHttpsContext(badSslConfig)
Http().superPool[MyTracker]()(httpMat)
我又添加了一个标记,但错误与之前不同:
val badSslConfig = AkkaSSLConfig().mapSettings(s => s.withLoose(s.loose.withAcceptAnyCertificate(true).withDisableHostnameVerification(true)))
val badCtx = Http().createClientHttpsContext(badSslConfig)
Http().superPool[MyTracker]()(httpMat)
错误:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[?:1.8.0_131]
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[?:1.8.0_131]
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[?:1.8.0_131]
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ~[?:1.8.0_131]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[?:1.8.0_131]
at sun.security.validator.Validator.validate(Validator.java:260) ~[?:1.8.0_131]
从answer获取灵感,不确定如何使用akka-httlp完全实现,我尝试了以下内容:
val trustStoreConfig = TrustStoreConfig(None, Some("/Users/user/path/my.cer")).withStoreType("PEM")
val trustManagerConfig = TrustManagerConfig().withTrustStoreConfigs(List(trustStoreConfig))
val sslConfig = AkkaSSLConfig().mapSettings { s =>
s.withHostnameVerifierClass(classOf[DisabledComplainingHostnameVerifier])
s.withTrustManagerConfig(trustManagerConfig)
s
}
val badCtx = Http().createClientHttpsContext(sslConfig)
Http().superPool[RequestTracker](badCtx)(httpMat)
但仍然收到此错误:
引起:java.security.cert.CertificateException:没有主题替代名称出现
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:144)〜[?:1.8.0_131]
at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)〜[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)〜[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)〜[?:1.8.0_131] 在sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)〜[?:1.8.0_131]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)〜[?:1.8.0_131]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1501)~ [?:1.8.0_131]
在Akka中这不可能吗?
答案 0 :(得分:0)
最后,从这个answer获取灵感,这似乎很复杂,下面的代码片段就可以了:
val trustStoreConfig = TrustStoreConfig(None, Some("/etc/Project/keystore/my.cer")).withStoreType("PEM")
val trustManagerConfig = TrustManagerConfig().withTrustStoreConfigs(List(trustStoreConfig))
val badSslConfig = AkkaSSLConfig().mapSettings(s => s.withLoose(s.loose
.withAcceptAnyCertificate(true)
.withDisableHostnameVerification(true)
).withTrustManagerConfig(trustManagerConfig))
val badCtx = Http().createClientHttpsContext(badSslConfig)
Http().superPool[RequestTracker](badCtx)(httpMat)
不确定为什么它不适用于我的其他尝试,想要深入理解,如果您了解内部,请发布解释。