Akka https ssl localhost testing



我正在尝试在本地设置akka-https,这样证书就不需要安装在每台服务器上(我希望它可以在jenkinsbuild或其他机器上运行(。

我用这种方式创建证书:

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", 2001, connectionContext = badCtx)

但是我有一个错误:

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

还尝试了此代码: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

相关内容

最新更新