微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Akka https ssl localhost测试

如何解决Akka https ssl localhost测试

我正在尝试在本地设置akka https,这种方式不需要在每台服务器上都安装证书(我希望它可以在jenkins构建版或其他计算机上运行)。

通过这种方式创建证书:

openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
cat server.crt server.key > cert.pem
openssl pkcs12 -export -in cert.pem -out mykeystore.pkcs12  -name akka-http-test -noiter -nomaciter

(也尝试使用mkcert工具)

现在的scala代码

def createHttpsContext(): HttpsConnectionContext = {
    val password: Array[Char] = "changeit".tochararray
    val ks: KeyStore = KeyStore.getInstance("PKCS12")
    val keystore: InputStream = {
      getClass.getClassLoader.getResourceAsstream("mykeystore.pkcs12")
    }

    require(keystore != null,"Keystore required!")
    ks.load(keystore,password)

    val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
    keyManagerFactory.init(ks,password)

    val tmf: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
    tmf.init(ks)

    val sslContext: SSLContext = SSLContext.getInstance("TLS")
    sslContext.init(keyManagerFactory.getKeyManagers,tmf.getTrustManagers,new SecureRandom)
    val https: HttpsConnectionContext = akka.http.scaladsl.ConnectionContext.httpsServer(sslContext)
    https
  }

def createHttpsApiServer()(implicit system: ActorSystem) = {
    val routes: Route = get { complete("Hello World!") }
    val httpsContext = createHttpsContext()
    Http().newServerAt("127.0.0.1",2001).enableHttps(httpsContext).bind(routes)
}

和测试代码

private def runStopServerHttpsRequest()(implicit system: ActorSystem): Unit = {
    val trustfulSslContext: HttpsConnectionContext = {
      object NoCheckx509trustmanager extends x509trustmanager {
        override def checkClientTrusted(chain: Array[X509Certificate],authType: String): Unit = ()
        override def checkServerTrusted(chain: Array[X509Certificate],authType: String): Unit = ()
        override def getAcceptedissuers: Array[X509Certificate] = Array[X509Certificate]()
      }
      val context = SSLContext.getInstance("TLS")
      context.init(Array[KeyManager](),Array(NoCheckx509trustmanager),null)
      context
      ConnectionContext.httpsClient(context)
    }

    val request = HttpRequest(HttpMethods.GET,"https://127.0.0.1:2001/")
    val connectionFlow = Http().outgoingConnectionHttps("127.0.0.1",2001,connectionContext = trustfulSslContext)

    Source.single(request).via(connectionFlow).runWith(Sink.head).map(x => (x.status,x.entity)).futureValue
  }

但是我遇到了错误

The future returned an exception of type: javax.net.ssl.SSLHandshakeException,with message: General SSLEngine problem.
ScalaTestFailureLocation: me.archdev.restapi.HttpSpec at (HttpSpec.scala:38)
org.scalatest.exceptions.TestFailedException: The future returned an exception of type: javax.net.ssl.SSLHandshakeException,with message: General SSLEngine problem.

任何想法如何解决这个问题?谢谢!

编辑: 香港专业教育学院试图也添加配置:

ssl-config {
  trustManager = {
      stores = [
        { type = "PKCS12",path = "src/main/resources/mykeystore.pkcs12",password = "changeit" }
      ]
  }
}

代码稍有变化:

l badSslConfig = AkkaSSLConfig().mapSettings(s => s.withLoose(s.loose
      .withAcceptAnyCertificate(true)
      .withdisableHostnameVerification(true)
    ))

    val badCtx = Http().createClientHttpsContext(badSslConfig)
    val connectionFlow = Http().outgoingConnectionHttps("127.0.0.1",connectionContext = badCtx)

但是我有一个错误

trustAnchors参数必须为非空 java.security.InvalidAlgorithmParameterException:trustAnchors 参数必须为非空

还尝试了以下代码https://gist.github.com/iRevive/4a3c7cb96374da5da80d4538f3da17cb

但随后:

[ERROR] [09/10/2020 08:51:38.088] [default-akka.actor.default-dispatcher-5] [akka://default/system/Materializers/StreamSupervisor-0/TLS-for-flow-3-1] the trustAnchors parameter must be non-empty
akka.actor.ActorInitializationException: akka://default/system/Materializers/StreamSupervisor-0/TLS-for-flow-3-1: exception during creation

还是一样。

解决方法

好的,这个终于奏效了:https://gist.github.com/iRevive/4a3c7cb96374da5da80d4538f3da17cb

在无法工作之前,因为我没有删除ssl-config.trustManager

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。