当前位置: 首页 > 知识库问答 >
问题:

如何从证书链、证书和私钥正确配置HTTPS?阿克卡HTTP

任繁
2023-03-14
  • 我必须使用Akka HTTP编程微服务。[完成]
  • 服务必须在docker容器内运行。[完成]
  • 与此服务的通信(通过REST API[完成])已经通过HTTPS。[TODO]

在尝试从Web浏览器发出HTTPS GET请求时:

浏览器警告连接不安全

在尝试向服务器上的服务发出cURL请求时:

docker ps

港口

0.0.0.0:443-

Curl-vhttps://localhost

  • TCP_NODELAY集
  • 对于4(传输0x5648dd24df90)在200 ms内过期
  • 连接到localhost(127.0.0.1)端口443(#0)
  • ALPN,提供h2
  • ALPN,提供超文本传输协议/1.1
  • 成功设置证书验证位置:
  • CAfile:无CApath: /etc/ssl/certs
  • TLSv1.3(OUT),TLS握手,客户你好(1):
  • OpenSSLSSL_connect:SSL_ERROR_SYSCALL连接到localhost:443
  • 关闭连接0 curl:(35)OpenSSLSSL_connect:SSL_ERROR_SYSCALL连接到localhost:443

如何正确配置Akka HTTP服务器以使用HTTPS,对于给定的:

  • 。pem文件(包含根证书和中间证书),
  1. 我将ca证书和我的证书连接到单个证书链。pem文件和私钥一起使用openssl创建了一个p12密钥存储
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

}

如果这还不够,完整的代码在我的公共存储库中

除了我读了很多关于x509标准和TLS/HTTP的内容,并在另一个线程中搜索答案之外,我还检查了服务器上的端口443是否打开(BTW:我在VPN连接内做所有事情,所以防火墙应该不重要??)我向管理员寻求帮助,他不熟悉Akka HTTP和docker,但他说curl输出可能与证书链有关。

共有3个答案

韦正业
2023-03-14

确保端口443已打开并正在运行

telnet localhost 443并查看是否有类似于scape字符为“^]”的内容

确保您的服务器使用https协议而不是http进行通信

curl——不安全-vhttps://localhost跳过SSL证书验证(但仍建立SSL连接),以查看是否确实收到服务器的响应

确保您的服务器证书是全局签名的,而不是自签名的

您的浏览器不信任未知证书,请确保您从全局CA获得SSL证书,例如SSL证书。让我们加密。您的浏览器有一个硬编码的CA证书列表,以验证每个网站的证书。

另一方面,您的curl在/etc/ssl/certs中查找,以获取用于验证网站证书的CA证书列表,因此标志--inSecurity是跳过验证SSL证书。

汪翰墨
2023-03-14

您正在传递nullTrustManager[]参数:

sslContext.init(X509KeyManagersFactory(p12KeyStore, keyStorePassword), null, new SecureRandom)

签出有关如何初始化和传递TrustManager的文档:https://doc.akka.io/docs/akka-http/current/server-side/server-https-support.html#using-https

温浩大
2023-03-14

令人尴尬的是,这个问题与Docker和使用openssl创建的密钥存储有关:容器中的根用户没有读取密钥存储的权限(权限被拒绝的异常)。

但是,代码是有效的,我将继续使用此线程作为社区的参考。

 类似资料:
  • 使用Azure Key Vault Secret client library for Python,我获得了证书的秘密,它有一个提取的私钥。

  • 因此,我正在通过 SAML2.0 为我们的应用程序实现 SSO。我们正在使用 saml2-js,并且我们正在执行 SP 启动的 SSO。 实现已经准备好了,它正在工作,但是有几个部分我还在纠结。 saml2-js要求您在ServiceProvider实例上提供私钥和证书-

  • 什幺是数字证书和数字证书链 上一节说到SSL/TLS协议是为了解决三大风险而设计,第三点就是防止身份被冒充,防止身份被冒充的核心关键就是数字证书和数字证书链。下面”直白”的方式说下数字证书和数字证书链。 为了保证信息在传输中的安全和双方的身份不被冒充,HTTPS在建立安全链接阶段使用了公钥、私钥两把“钥匙”——非对称加密。非对称意思是:公钥加密的内容,只有私钥才能解密。私钥加密的内容,只有公钥才能

  • 我使用< code > SSL _ get _ peer _ certificate(),< code > X509 _ get _ pubkey() API获取网站(www.google.com)https证书公钥,转储公钥时如下: 我发现这和我在浏览器中看到的不一样(在Chrome中,点击URL地址栏中的挂锁,<代码>- 为什么这两种公钥不一样? 我很好奇这两种公钥数据是什么? 更新: 从Ch

  • a.从存储区提取现有证书密钥: b.从导出的证书中提取私钥: 没有证书与私钥匹配 我错过了什么?为什么我的最后一个命令不合法? 我计划执行“keytool-importkeystore”文件。p12(应该在最后一步中生成)来替换“keystore”中的“一个”privateKeyEntry。正如在如何导入Java keystore中现有的x509证书和私钥以便在SSL中使用中所建议的?。基本上,我