【问题标题】:What does a PHP developer need to know about https / secure socket layer connections?PHP 开发人员需要了解有关 https / 安全套接字层连接的哪些信息?
【发布时间】:2010-09-09 01:00:26
【问题描述】:

关于 https 连接的方式和原因,我几乎一无所知。显然,当我传输密码或信用卡信息等安全数据时,https 是一个关键工具。不过,我需要知道什么?您看到开发人员在项目中实施时最常犯的错误是什么?有时https只是个坏主意吗?谢谢!

【问题讨论】:

  • 除了以下内容之外,您还应该使用 Wireshark 查看一个简单的 HTTPS 请求/响应,以便查看它“正在运行”。并且在下面的答案中暗示您了解公钥密码术(在高层次上)。

标签: php security ssl https


【解决方案1】:

确保在 HTTPS 页面上时,页面上的所有元素都来自 HTTPS 地址。这意味着元素应该具有相对路径(例如“/images/banner.jpg”)以便继承协议,或者您需要检查每个页面以找到协议,并将其用于所有元素。

注意:这包括所有外部资源(如 Google Analytics javascript 文件)!

我能想到的唯一缺点是它增加了(几乎可以忽略不计的)浏览器和服务器的处理时间。我建议只加密需要的传输。

【讨论】:

  • Google Analytics 的代码自行检测 HTTPS 并从安全服务器提供服务。他们已经使用了一年多,使用旧代码的用户可以随时升级。
  • 嘿,谢谢。我不知道。我想我应该多读一些他们的博客 ;-)
  • 如果您要让第三方来源的内容进入,这是否会破坏安全页面的目的。尤其是 Javascript 文件(如 Google 分析)可能充当键盘记录器并将安全信息发送给第三方?
【解决方案2】:

我建议任何时候任何用户数据存储在数据库中并进行通信,使用 https。即使用户数据是平凡的,也要考虑这一要求,因为即使是这些平凡的细节中的许多也被该用户用于在其他网站上识别自己的身份。考虑一下你的银行问你的所有随机安全问题(比如你住在哪条街上?)。这可以很容易地从地址字段中获取。在这种情况下,数据不是您认为的密码,但也可能是密码。此外,您永远无法预料哪些用户数据将用于其他地方的安全问题。您还可以预期,凭借普通网络用户(想想您的祖母)的智慧,这些信息可能会在其他地方构成该用户密码的一部分。

如果您使用 https,则为一个指针

如果用户键入 http://www.website-that-needs-https.com/etc/yadda.php 他们将自动被重定向到 https://www.website-that-needs-https.com/etc/yadda.php (个人的烦恼)

但是,如果您只是在做一个普通的 html 网页,那本质上是从服务器到用户的单向传输信息,不用担心。

【讨论】:

    【解决方案3】:

    我想说,使用启用 SSL 的网站时最常见的错误是

    1. 该网站错误地将用户从页面重定向到 http 作为 https
    2. 网站不会在必要时自动切换到 https
    3. https 页面上的图像和其他资产正在通过 http 加载,这将触发来自浏览器的安全警报。确保所有资产都使用指定 https 的完全限定 URI。
    4. 安全证书仅适用于一个子域(例如 www),但您的站点实际上使用了多个子域。如果需要,请确保获得通配符证书。

    【讨论】:

      【解决方案4】:

      为网站提供 HTTPS 或安全套接字层 (SSL) 证书,通常由证书颁发机构 (CA) 签署,该证书颁发机构实际上是受信任的第三方,可验证有关您网站的一些基本详细信息,并证明它用于浏览器。如果您的浏览器信任 CA,则它信任由该 CA 签名的任何证书(这称为信任链)。

      每个 HTTP(或 HTTPS)请求都由两部分组成:请求和响应。当您通过 HTTPS 请求某些内容时,实际上会在后台发生一些事情:

      • 客户端(浏览器)进行“握手”,请求服务器的公钥和标识。
        • 此时,浏览器可以检查有效性(站点名称是否匹配?日期范围是当前的吗?它是否由它信任的 CA 签名?)。它甚至可以联系 CA 并确保证书有效。
      • 客户端创建一个新的 pre-master secret,使用服务器的公钥加密(因此只有服务器可以解密)并发送给服务器
      • 服务器和客户端都使用此预主密钥生成主密钥,然后使用该主密钥创建用于实际数据交换的对称会话密钥
      • 双方发送消息说他们已完成握手
      • 服务器然后正常处理请求,然后使用会话密钥对响应进行加密

      如果连接保持打开状态,则每个连接都将使用相同的对称密钥。

      如果建立了新连接,并且双方仍然拥有主密钥,则可以在“简短握手”中生成新的会话密钥。通常,浏览器会存储一个主密钥直到它关闭,而服务器会存储它几分钟或几个小时(取决于配置)。

      有关会话长度的更多信息,请参阅How long does an HTTPS symmetric key last?

      证书和主机名

      证书被分配了一个通用名称 (CN),对于 HTTPS,它是域名。 CN 必须完全匹配,例如,CN 为“example.com”的证书将与域“www.example.com”不匹配,用户将在浏览器中收到警告。

      SNI 之前,无法在一个 IP 上托管多个域名。因为证书是在客户端甚至发送实际的 HTTP 请求之前获取的,并且 HTTP 请求包含 Host: 标头行,告诉服务器使用哪个 URL,服务器无法知道为给定的服务提供什么证书要求。 SNI 将主机名添加到 TLS 握手的一部分,因此只要客户端和服务器都支持它(在 2015 年,它被广泛支持),那么服务器就可以选择正确的证书。

      即使没有 SNI,提供多个主机名的一种方法是使用包含主题备用名称 (SAN) 的证书,这些证书本质上是证书有效的附加域。例如,Google 使用一个证书来保护它的许多网站。

      另一种方法是使用通配符证书。可以获得像“.example.com”这样的证书,在这种情况下,“www.example.com”和“foo.example.com”都对该证书有效。但是,请注意“example.com”与“.example.com”不匹配,“foo.bar.example.com”也不匹配。如果您使用“www.example.com”作为证书,则应将“example.com”上的任何人重定向到“www”。地点。如果他们请求https://example.com,除非您将其托管在单独的 IP 上并拥有两个证书,否则将收到证书错误。

      当然,您可以同时使用通配符和 SAN(只要您的 CA 允许您这样做)并为“example.com”和 SAN“.example.com”、“example .net”和“.example.net”,例如。

      表格

      严格来说,如果你是提交一个表单,那么表单页面本身是否没有加密也没关系,只要提交的 URL 是一个 https:// 的 URL。实际上,用户已经被训练(至少在理论上)不要提交页面,除非他们看到小“锁定图标”,所以即使是表单本身也应该通过 HTTPS 提供服务来获得这个。

      流量和服务器负载

      HTTPS 流量比同等的 HTTP 流量大得多(由于加密和证书开销),而且它也给服务器带来了更大的压力(加密和解密)。如果您有一个负载很重的服务器,则可能需要对使用 HTTPS 提供哪些内容非常有选择性。

      最佳做法

      • 如果您不只是对整个站点使用 HTTPS,它应该会根据需要自动重定向到 HTTPS。每当用户登录时,他们都应该使用 HTTPS,如果您使用会话 cookie,则 cookie 应该有 secure flag set。这可以防止截获会话 cookie,鉴于开放(未加密)wifi 网络的普及,这一点尤其重要。

      • 页面上的任何资源都应该来自页面使用的相同方案。如果您在使用 HTTPS 加载页面时尝试从 http:// 获取图像,用户将收到安全警告。您应该使用完全限定的 URL,或者另一种简单的方法是使用不包含主机名的绝对 URL(例如,src="/images/foo.png"),因为它们适用于两者。

        • 这包括外部资源(例如,Google Analytics)
      • 从 HTTPS 更改为 HTTP 时不要执行 POST(表单提交)。大多数浏览器都会将此标记为安全警告。

      【讨论】:

      • 客户端既不发送其公钥,也不动态生成公钥。 SSL 使用对称加密,而不是非对称加密 (PKI)。
      • @EJP 你说得对,我对那部分做了更新。知道我现在所知道的(我写这篇文章已经 8 年了)这只是主题的表面,还有很多关于 SSL 密钥和握手的细微差别没有涵盖(例如:不同的密钥交换算法,第 4 层 vs第 7 层负载均衡器和 ssl 卸载与桥接)。
      【解决方案5】:

      这里的所有非常好的提示......但我只想添加一些东西......
      我见过一些网站给你一个 http 登录页面,只有在你发布用户名/密码后才会将你重定向到 https。这意味着在建立 https 连接之前用户名是明文传输的。

      简而言之,创建从 ssl 登录的页面,而不是发布到 ssl 页面。

      【讨论】:

        【解决方案6】:

        我不打算深入探讨 SSL,gregmac 在这方面做得很好,见下文 ;-)。

        然而,在使用 SSL/TLS 方面,一些最常见(和关键)的错误(不是专门的 PHP):

        1. 在应该强制执行 HTTPS 时允许 HTTP
        2. 通过 HTTP 从 HTTPS 页面检索一些资源(例如图像、IFRAME 等)
        3. 无意中从 HTTPS 页面定向到 HTTP 页面 - 请注意,这包括“虚假”页面,例如“about:blank”(我已经看到它用作 IFRAME 占位符),这将不必要且令人不快地弹出警告。

        4. Web 服务器配置为支持旧的、不安全的 SSL 版本(例如 SSL v2 很常见,但严重损坏) (好吧,这不完全是程序员的问题,但有时没有其他人会处理它......)

        5. Web 服务器配置为支持不安全的密码套件(我见过 NULL 密码仅在使用中,它基本上完全不提供加密) (同上)

        6. 自签名证书 - 防止用户验证网站的身份。

        7. 从 HTTP 页面请求用户的凭据,即使提交到 HTTPS 页面也是如此。同样,这可以防止用户在提供密码之前验证服务器的身份......即使密码是加密传输的,用户也无法知道他是否在一个虚假网站上 - 或者即使它会被加密。

        8. 非安全 cookie - 与安全相关的 cookie(如 sessionId、身份验证令牌、访问令牌等)必须设置为“安全”属性集。这个很重要!如果未设置为安全,则安全 cookie,例如SessionId,可以通过 HTTP 传输(!) - 攻击者可以确保这会发生 - 从而允许会话劫持等。当你在它时(虽然这不是直接相关的),也可以在你的 cookie 上设置 HttpOnly 属性(有助于缓解一些 XSS)。

        9. 过于宽松的证书 - 假设您有多个子域,但并非所有子域都处于相同的信任级别。例如,您有 www.yourdomain.com、dowload.yourdomain.com 和 publicaccess.yourdomain.com。因此,您可能会考虑使用通配符证书......但您也有secure.yourdomain.com 或finance.yourdomain.com - 即使在不同的服务器上。然后 publicaccess.yourdomain.com 将能够冒充secure.yourdomain.com .... 虽然在某些情况下这样做是可以的,但通常您需要一些权限分离......

        目前就记得这么多了,以后可能会重新编辑...

        至于什么时候使用 SSL/TLS 是个坏主意 - 如果您拥有不针对特定受众(单个用户或注册成员)的公共信息,并且您并不特别关注他们检索它专门来自正确的来源(例如股票代码值必须来自经过身份验证的来源......) - 那么没有真正的理由产生开销(而不仅仅是性能...... dev/test/cert/etc)。

        但是,如果您的站点与另一个更敏感的站点之间共享资源(例如同一台服务器),那么更敏感的站点应该在此处设置规则。

        此外,密码(和其他凭据)、信用卡信息等应始终通过 SSL/TLS。

        【讨论】:

          【解决方案7】:

          我发现尝试<link> 到一个不存在的样式表也会导致安全警告。当我使用正确的路径时,会出现锁定图标。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多