介绍
问题
尝试从 Web 浏览器发出 HTTPS GET 请求时:
Browser warning connection not secure
尝试向服务 发出 cURL 请求时在服务器上 :
docker ps
端口
0.0.0.0:443->443/tcp
curl -v https://localhost
CApath:/etc/ssl/certs
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL 连接到 localhost:443
问题
如何正确配置 Akka HTTP 的服务器以使用 HTTP 小号 , 对于给定的:
到目前为止我做了什么?
package de.htw_berlin.http
import java.security.SecureRandom
import akka.http.scaladsl.{ConnectionContext, HttpsConnectionContext}
import de.htw_berlin.security.{PKCS12KeyStoreFactory, X509KeyManagersFactory}
import java.io.FileInputStream
import javax.net.ssl.SSLContext
object HttpsConnectionContextFactory {
// TODO refactor
def apply(keyStoreFilename: String, keyStorePassword: String): HttpsConnectionContext = {
val p12KeyStore = PKCS12KeyStoreFactory(new FileInputStream(keyStoreFilename), keyStorePassword)
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(X509KeyManagersFactory(p12KeyStore, keyStorePassword), null, new SecureRandom)
ConnectionContext.httpsServer(sslContext)
}
}
package de.htw_berlin.security
import java.security.KeyStore
import javax.net.ssl.{KeyManager, KeyManagerFactory}
object X509KeyManagersFactory {
def apply(keyStore: KeyStore, keyStorePassword: String): Array[KeyManager] = {
val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray)
keyManagerFactory.getKeyManagers
}
}
package de.htw_berlin.security
import java.io.InputStream
import java.security.KeyStore
object PKCS12KeyStoreFactory {
def apply(keyStoreAsInputStream: InputStream, keyStorePassword: String): KeyStore = {
val p12KeyStore = KeyStore.getInstance("PKCS12")
p12KeyStore.load(keyStoreAsInputStream, keyStorePassword.toCharArray)
p12KeyStore
}
}
package de.htw_berlin.http
import akka.actor.typed.ActorSystem
import akka.http.scaladsl.Http.ServerBinding
import akka.http.scaladsl.{Http, HttpsConnectionContext}
import de.htw_berlin.http.dip.RequestHandler
import scala.concurrent.Future
// TODO test.
/** Represents a HTTPS server which can be bind to a host and port.
* The server needs a request handler for processing incoming requests.
*
* @param host the optional host of the server. The default value is Constants.DefaultServerIpv4Address.
* @param port the optional port number of the server. The default value is Constants.DefaultHttpsPort.
* @param httpsContext the https connection context for the https connection.
* @param actorSystem an implicit actor system.
* @see de.htw_berlin.http.dip.RequestHandler
*/
class Server(val host: String = Constants.DefaultServerIpv4Address,
val port: Int = Constants.DefaultHttpsPort,
val httpsContext: HttpsConnectionContext)(implicit val actorSystem: ActorSystem[Nothing]) {
/** Binds the current server to the endpoint parameters (host and port) and uses the passed
* handler for processing incoming connections.
*
* @param handler the handler to be used for processing incoming requests.
* @return a server binding future.
*/
def bindAndHandleWith(handler: RequestHandler): Future[ServerBinding] =
Http().newServerAt(host, port).enableHttps(httpsContext).bind(handler.getRoute)
}
package de.htw_berlin.http
/** This object contains constants related with the current module http. */
object Constants {
/** The server's default IPv4 address. */
val DefaultServerIpv4Address = "0.0.0.0"
/** The default port for HTTPS connections. */
val DefaultHttpsPort = 443
}
不够的话,完整代码在我的公众号repository我还做了什么
除了我阅读了很多关于 x509 标准和 TLS/HTTP 并在另一个线程中搜索答案的事实之外,我还检查了服务器上的端口 443 是否打开(顺便说一句:我在 VPN 连接中做所有事情,所以防火墙应该没关系??)我向管理员寻求帮助,他不熟悉 Akka HTTP 和 docker,但他说 curl 输出可能与证书链有关。
最佳答案
尴尬的是,问题与 Docker 和使用 openssl 创建的 keystore 有关:容器内的 root 用户没有读取 keystore 的特权(权限被拒绝异常)。
但是,代码有效,我将继续将此线程作为社区的引用。
关于scala - 如何从证书链、证书和私钥正确配置 HTTPS?阿卡 HTTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65327030/