【问题标题】:Hows is ssl certificate verified and by a browser or server如何通过浏览器或服务器验证 ssl 证书
【发布时间】:2016-12-23 08:53:21
【问题描述】:

我创建了一个自签名证书

$ openssl genrsa -out key.pem 1024
$ openssl req -new -key key.pem -out request.csr
$ openssl x509 -req -in request.csr -signkey key.pem -out cert.pem

并创建了一个 HTTPS 服务器:

var server = https.createServer({
    key: fs.readFileSync(__dirname + "/key.pem"),
    cert: fs.readFileSync(__dirname + "/cert.pem")
}

然后我请求了该页面。预期的结果是浏览器抱怨连接不安全。我的问题是浏览器如何知道这一点?验证证书并通知浏览器是服务器工作还是浏览器工作?

【问题讨论】:

标签: javascript node.js ssl https


【解决方案1】:

SSL 证书由客户端验证。

服务器通常会在启动时验证证书没有损坏或损坏,但大多数服务器实际上并不验证其证书的合法性。

为什么要验证证书?

验证服务器证书很重要,否则客户端无法真正知道它正在与谁通信。 MITM(中间人)攻击可能发生在第三方拦截通信双方的情况下,他们可以向您提供他们的数据,而不是您认为您正在接收的来自服务器的数据。

关于证书类型的一点点

大多数证书由 CA 签名,也有自签名证书和固定证书。我建议尽可能使用由 CA 签署的证书。第二个最佳选项(通常只能在组织内使用)将使用您自己的内部 CA,然后使用您的 CA 证书自签名您的服务器证书,这被称为自签名证书,它不会被信任由任何接收它的客户端或浏览器自动生成。

在自签名选项中,您必须将您的 CA 公钥导入您的 CA 密钥库,以使您的服务器证书受到信任。最后有一个简单的固定证书,在这里您只需告诉浏览器信任其他不受信任的证书(不要这样做)。

警告 - 您应该避免固定证书,因为它们在入侵期间几乎不可能被替换,并且证书应该安排在合理的期限内到期,并定期轮换。在某些情况下,即使几乎不可能,固定也非常困难。

证书类型

  • CA 签名(需要在 WWW 上运行安全站点)
  • 自签名(适合内部组织使用,例如公司内部 wiki)
  • 固定(避免)

会发生什么样的验证?

所以你有一个证书,首先你配置你的服务器来使用那个证书。

现在,当客户端出现并请求与您的站点建立安全连接时(如在 HTTPS 情况下连接到端口 443 所示)。您的服务器发送它的公共(非私有)证书并开始安全握手。一种这样的握手称为Diffie–Hellman key exchange握手本身超出了这个问题的范围。

在参与密钥交换之前,浏览器将首先检查服务器提供的证书。要使其有效,必须成功进行多项检查。

执行了一些检查。

  • 此证书是否包含与我们连接的主机名匹配的主机名?

    • 如果否,证书是否包含通配符 CN(通用名称)?
      • 如果是,该 CN 是否具有与我们连接的主机名匹配的有效“通配符”? 是/否
  • 证书是否包含 CRL(证书吊销列表)?如果是这样,该 CRL 是否表明该证书仍然有效? 是/否

  • 此证书是否由已知的证书颁发机构 (CA) 签署? 是/否

    • 仅当否时,此客户端(浏览器)是否具有已标记为受信任的公共证书(与此服务器提供的证书匹配)? 是/否 *这也称为固定证书,因为您不依赖 CA 来验证其真实性。

让浏览器信任证书,并通过代理服务器。然后我们必须检查上面的每个“是”框

其他让世界更安全的安全产品

现在还有其他不是证书“特定”的东西也经过验证。

例如,客户端和服务器必须就握手方法、使用的密码、使用的散列算法等达成一致。

服务器还可以传递特殊的 HTTPS 安全标志,指示浏览器在一段时间内不信任此服务的其他证书(这称为证书固定)。像“严格传输安全”中使用的证书固定(不要与上面提到的固定证书混淆)可以帮助防止 MITM(中间人)攻击。这是HTTPS Strict Transport Security 提供的众多额外安全功能之一。

一旦所有的安全检查都通过了认证,浏览器就会向服务器发送它所拥有的任何请求,并且服务器会做出适当的响应。

【讨论】:

  • 问题目前缺少信息为什么客户端必须检查证书以及为什么客户端仅仅相信服务器已经检查证书作为验证选项提供的 OP 是不够的.
  • 我认为你的意思是回答。首先,请求者没有提出这些问题,请求者询问“如何验证证书”。但我会在帖子中为你回答这两个问题。
【解决方案2】:

当您访问受保护的网站(使用 https)时,服务器还会发送由权威机构签署的证书以证明其身份(这样您就知道您不会被人夹在中间)。

然后,您的浏览器需要知道证书是否真实,因为中间的人也可以发送证书。幸运的是,您的浏览器有一个值得信任的权威列表。如果证书的授权签名与受信任的授权之一匹配,则一切正常,不会发出警报。

但是如果没有匹配的权限,那么浏览器会询问您我们是否可以信任这个权限。在自签名证书的情况下,您可以信任它(但在验证指纹之前不能信任它,因为中间的人可能会再次发送不同的证书来欺骗您相信它们是真实的交易)。

如果您信任它,则浏览器会导入它并将其添加到要信任的证书中,不再发出警报(直到您的证书过期或更改(就像处于中间情况的人一样))。

【讨论】:

  • 谢谢,您能否定义流程如何完成或提供描述流程的资源链接?我想知道以a browser sends Upgrade-Insecure-Requests:1 header...开始的步骤
  • 这取决于您的操作系统,但快速搜索会返回:for Windows, for Firefox on Linux
  • 谢谢,您的回答更像是评论。你能用一个过程描述来详细说明一下吗?您提供的链接没有太大帮助。据说我必须导入一些东西,虽然我在访问不同的 http 网站时从不导入任何东西
  • 我编辑了它,但我不知道您是否想知道它是如何工作的或如何导入证书,因为您的问题只是关于“它是服务器端还是浏览器端”。跨度>
  • Man in the Middle 也可以颁发证书吗?在我看来,如果Man in the Middle 可以颁发证书,则没有任何用处,因为一旦验证了证书,连接就会被加密。由于客户端-服务器连接是通过 SSL 加密的,Man in the Middle 无法读取沿连接传输的数据。如果我刚才所说的有误,您可以提供有效的解释。
【解决方案3】:

验证证书并通知浏览器是服务器工作还是浏览器工作?

服务器证书的主要作用是确保客户端正在与预期的服务器进行通信。 如果客户端(浏览器)只是信任证书有效的服务器,那么中间攻击者可以简单地声称是真正的服务器并声称证书是有效的。在此之后,客户端将与攻击者而不是真实服务器建立加密连接,这意味着攻击者可以访问敏感数据。因此,客户端必须始终正确检查服务器证书。

我的问题是浏览器如何知道这一点?

简而言之:通过检查颁发者的签名并遵循信任链直到本地受信任的根证书来检查证书是否受信任,同时检查 URL 的主机名是否与证书的主题匹配以及证书仍然有效,即未过期且未撤销。更多详情请见SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate?

【讨论】:

  • 这个答案没有恰当地回答请求者的问题。
  • @JoshuaBriefman:现在好点了吗?如果不是,请解释而不是抱怨。
  • 不鼓励主要是“链接到答案”的答案,因为该内容将来可能会出现,也可能不会出现。你的答案应该包含你的完整答案。但是,您可以将外部链接作为参考/引文引用。请以我的回复为例。
猜你喜欢
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 2012-11-14
  • 2015-06-24
  • 1970-01-01
  • 2012-12-04
相关资源
最近更新 更多