关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » HTML5 »如何在 Apache、Ngnix 和 Lighttpd 上启用 HTTP 公钥固定扩展

    如何在 Apache、Ngnix 和 Lighttpd 上启用 HTTP 公钥固定扩展

    2015-04-26 00:00:00 出处:linux.cn
    分享

    编者按:前段时间,Google 报告说 CNNIC 签发的一个中级 CA 签发了一个伪造的 Google 证书,从而导致 Google 和 Mozilla 在其产品中取消了对 CNNIC 后继签发的证书信任。

    本文就来讲述一下,这种伪造证书是如何被 Google 发现的,其技术机制是什么?如何在网站服务器上实现伪造证书防御和报告机制。

    公钥固定(Public Key Pinning)是指一个证书链中必须包含一个白名单中的公钥,也就是说只有被列入白名单的证书签发机构(CA)才能为某个域名*.example.com签发证书,而不是你的浏览器中所存储的任何 CA 都可以为之签发。本文讲述了这种机制的背景知识,并提供了 Apache、 Lighttpd 和 NGINX 上的配置范例。

    在 Apache、NGINX 和 Lighttpd 上启用 HTTP 公钥固定扩展(HPKP)

    HTTP 公钥固定扩展

    用你使用的银行做个例子,它一直使用 CA 公司 A 为其签发证书。但是在当前的证书体系下,CA 公司 B、CA 公司 C 和 NSA 的 CA 都能给你的银行创建证书,而你的浏览器会毫无疑虑的接受它们,因为这些公司都是你所信任的根 CA。

    假如你的银行实现了 HPKP 并固定了它们的第一个中级证书(来自 CA 公司 A),那么浏览器将不会接受来自CA 公司 B 和 CA 公司 C 的证书,即便它们也有一个有效的信任链。HPKP 也允许你的浏览器将这种违例行为报告给该银行,以便银行知道被伪造证书攻击了。

    HTTP 公钥固定扩展是一个从2011年开始开发的针对 HTTP 用户代理(即浏览器)的公钥固定标准。它由 Google 发起,甚至在 Chrome 中实现的固定机制可以使用一个人工维护的网站公钥固定列表,这个列表包含了固定的几个网站的公钥签名。(LCTT 译注:Chrome 和 FireFox 32 及以后版本都支持公钥固定机制,并使用内置的人工维护的公钥固定列表数据,这些数据随着浏览器软件的更新而更新,主要包括几个大型站点。目前还只有 Chrome 38+ 支持通过 HTTP 响应头传递公钥固定信息。)

    以下是 HPKP 的几个功能简述:

    HPKP 是在 HTTP 层面设置的,使用 Public-Key-Pins (PKP)响应头。 该规则的保留周期通过 max-age 参数设置,单位是秒。 PKP 响应头只能用于正确的安全加密通讯里面。 假如出现了多个这样的响应头,则只处理第一个。 固定机制可以使用includeSubDomains参数扩展到子域。 当接收到一个新的 PKP 响应头时,它会覆盖之前存储的公钥固定和元数据。 公钥固定是用哈希算法生成的,其实是一个“主题公钥信息(SKPI)”指纹。

    本文首先会介绍一些 HPKP 工作的原理,接下来我们会展示给你如何得到需要的指纹并配置到 web 服务器中。

    SPKI 指纹 – 理论

    以下摘自 Adam Langley 的帖子,我们哈希的是一个公钥,而不是证书:

    通常来说,对证书进行哈希是一个显而易见的解决方案,但是其实这是错的。不能这样做的原因是 CA 证书可以不断重新签发:同一个公钥、主题名可以对应多个证书,而这些证书有不同的延展或失效时间。浏览器从下至上地在证书池中构建证书链时,另外一个版本的证书可能就替代匹配了你原本所期望的证书。

    举个例子,StartSSL 有两个根证书:一个是以 SHA1 签名的,另外是一个是 SHA256。假如你希望固定住 StartSSL 作为你的 CA,那么你该使用哪个证书呢?你也许可以使用这两个,但是假如我不告诉你,你怎么会知道还有一个根证书呢?

    相反地,对公钥进行哈希则不会有这个问题:

    浏览器假定子证书是固定不动的:它总是证书链的起点。子证书所携带的签名一定是一个有效的签名,它来自其父证书给这个证书专门签发的。这就是说,父证书的公钥相对于子证书来说是固定的。所以可推论公钥链是固定的。

    唯一的问题是你不能固定到一个交叉认证的根证书上。举个例子,GoDaddy 的根证书是 Valicert 签名的,这是为了让那些不能识别 GoDaddy 根证书的老客户可以信任其证书。然而,你不能固定到 Valicert 上,因为新的客户在证书链上发现了 GoDaddy 证书就会停止上溯(LCTT 译注:所以就找不到固定信息了)。

    此外,我们是对 SubjectPublicKeyInfo(SPKI)进行哈希而不是对公钥位串。SPKI 包括了公钥类型、公钥自身及其相关参数。这很重要,因为假如对公钥进行哈希就有可能导致发生曲解攻击。对于一个 Diffie-Hellman 公钥而言:假如仅对公钥进行哈希,而不是对完整的 SPKI,那么攻击者可以使用同样的公钥而让客户端将其解释为其它组。同样地,这样也有可能强制将一个 RSA 密钥当成 DSA 密钥解释等等。

    固定在哪里

    你应该固定在什么地方?固定你自己的公钥并不是一个最好的办法。你的密钥也许会改变或撤销。你也许会使用多个证书,经常轮换证书的话密钥就改变了。也许由于服务器被入侵而撤销证书。

    最容易但是不是太安全的方法是固定第一个中级 CA 证书。该证书是签名在你的网站证书之上的,所以签发该证书的 CA 的公钥肯定是在证书链上的。

    采用这种方法你可以从同一个 CA 更新你的证书而不用担心固定信息不对。假如该 CA 发行了一个不同的根证书,也许你会遇到一些问题,对此并没有太好的解决方案。不过你可以通过如下做法来减轻这种问题的影响:

    从一个不同的 CA 申请一个备用的证书,并固定该备份。

    RFC 里面说你至少需要做两个固定。一个是当前连接所使用的证书链上的,另外一个是备份的。

    另外的固定是对备份公钥的,它可以是来自另外一个给你签发证书的不同 CA 的 SKPI 指纹。

    在这个问题上还有一种更安全的方法,就是事先创建好至少三个独立的公钥(使用 OpenSSL,参见此页 了解 Javascript OpenSSL 命令生成器),并将其中两个备份到一个安全的地方,离线存储、不要放到网上。

    为这三个证书创建 SPKI 指纹并固定它们,然后仅使用第一个作为当前的证书。当需要时,你可以使用备份密钥之一。不过你需要让 CA 给你做签名来生成证书对,这可能需要几天,依你的 CA 的工作情况而定。

    对于 HPKP 来说这没有问题,因为我们使用的是公钥的 SPKI 哈希,而不是证书。失效或不同的 CA 签名链并不影响。

    假如你按照上述方法生成并安全存储了至少三个独立的密钥,并固定它们,也可以防止你的 CA 撤销你的网站证书并签发一个假证书时出现问题。

    SPKI 指纹

    可以使用如下的 OpenSSL 命令来生成 SPKI 指纹,它出现在 RFC 草案 中:

    openssl x509 -noout -in certificate.pem -pubkey | /
    openssl asn1parse -noout -inform pem -out public.key;
    openssl dgst -sha256 -binary public.key | openssl enc -base64

    结果:

    klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=

    上面输入的 certificate.pem 文件是本站(https://raymii.org)的证书链中第一个证书。(在写本文时, COMODO RSA Domain Validation Secure Server CA, 序列号 2B:2E:6E:EA:D9:75:36:6C:14:8A:6E:DB:A3:7C:8C:07 )。

    你也需要同样对你的另外两个备份公钥生成指纹。

    故障

    在写本文时(2015/1),唯一支持 HPKP 的浏览器(chrome)有一个严重的问题:Chrome 并不能够区分 HSTS 和 HPKP 响应头中的 max-age 和 includeSubdomains 参数。也就是说,假如你的 HSTS 和 HPKP 设置了不同的 max-age 和 includeSubdomains 参数,它们会互相搞乱。关于这个故障的更多信息参见:https://code.google.com/p/chromium/issues/detail id=444511。感谢 Scott Helme(https://scotthelme.co.uk)发现并告诉我这个 Chromium 项目的问题。

    Web 服务器配置

    下面你可以看到三个主流 Web 服务器的配置方法。这只是一个 HTTP 响应头,绝大多数 Web 服务器都可以设置它。它只需要设置到 HTTPS 网站上。

    下面的例子固定到 COMODO RSA Domain Validation Secure Server CA 及备份的 Comodo PositiveSSL CA 上,30天失效期,包括所有的子域。

    Apache

    编辑你的 Apache 配置文件(如 /etc/apache2/sites-enabled/website.conf 或 /etc/apache2/httpd.conf),并添加下列行到你的 virtualHost 中:

    # 如需要,载入 headers 模块。
    LoadModule headers_module modules/mod_headers.so
    
    Header set Public-Key-Pins "pin-sha256=/"klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=/"; pin-sha256=/"633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q=/"; max-age=2592000; includeSubDomains"

    Lighttpd

    Lighttpd 更简单一些,将下列行添加到你的 Lighttpd 配置文件(如 /etc/lighttpd/lighttpd.conf):

    server.modules += ( "mod_setenv" )
    $HTTP["scheme"] == "https" {
        setenv.add-response-header  = ( "Public-Key-Pins" => "pin-sha256=/"klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=/"; pin-sha256=/"633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q=/"; max-age=2592000; includeSubDomains")
    }

    NGINX

    NGINX 的配置更简短。添加以下行到你的 HTTPS 配置的 server 块中:

    add_header Public-Key-Pins 'pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q="; max-age=2592000; includeSubDomains';

    报告功能

    HPKP 报告功能允许浏览器报告任何违例给你。

    假如你在响应头中添加了附加的 report-uri=”http://example.org/hpkp-report” 参数,并用该 URI 处理接收到的数据的话,客户端会在发现违例时发送报告给你。这个报告是以 POST 方式发送到你指定的 report-uri 上,并以类似下面的 JSON 格式:

    {
        "date-time": "2014-12-26T11:52:10Z",
        "hostname": "www.example.org",
        "port": 443,
        "effective-expiration-date": "2014-12-31T12:59:59",
        "include-subdomains": true,
        "served-certificate-chain": [
            "-----BEGINCERTIFICATE-----/nMIIAuyg[...]tqU0CkVDNx/n-----ENDCERTIFICATE-----"
        ],
        "validated-certificate-chain": [
            "-----BEGINCERTIFICATE-----/nEBDCCygAwIBA[...]PX4WecNx/n-----ENDCERTIFICATE-----"
        ],
        "known-pins": [
            "pin-sha256=/"dUezRu9zOECb901Md727xWltNsj0e6qzGk/"",
            "pin-sha256=/"E9CqVKB9+xZ9INDbd+2eRQozqbQ2yXLYc/""
        ]
    }

    非强制,只报告

    HPKP 也可以设置为非强制的,可以使用 Public-Key-Pins-Report-Only 来只发送违例报告给你。

    这样可以让你在网站不可访问或 HPKP 配置不正确时不固定,之后你可以将这个响应头改为 Public-Key-Pins 来强制固定。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    帝国CMS7.5编辑器上传图片取消宽高的三种方法

    帝国cms如何自动生成缩略图的实现方法

    Windows 12即将到来,将彻底改变人机交互

    帝国CMS 7.5忘记登陆账号密码怎么办?可以phpmyadmin中重置管理员密码

    帝国CMS 7.5 后台编辑器换行,修改回车键br换行为p标签

    Windows 11 版本与 Windows 10比较,新功能一览

    Windows 11激活产品密钥收集及专业版激活方法

    如何从 Windows 11 中完全删除/卸载 OneNote?无解!

    抖音安全与信任开放日:揭秘推荐算法,告别单一标签依赖

    ultraedit编辑器打开文件时,总是提示是否转换为DOS格式,如何关闭?

    IT头条

    华为Pura80系列新机预热,余承东力赞其复杂光线下的视频拍摄实力

    01:28

    阿里千问3开源首战告捷:全球下载破千万,国产AI模型崛起新高度!

    01:22

    DeepSeek R1小版本试升级:网友实测编程能力已达到国际一线水平

    23:15

    NVIDIA 与 Dell 合作,大规模交付 Blackwell AI 系统

    20:52

    Cerebras 以最快的 Llama 4 Maverick 性能引领 LLM 推理竞赛

    20:51

    技术热点

    PHP中的随机性——你觉得自己幸运吗?

    搞定Ubuntu Linux下WPA无线上网

    Java使用内存映射实现大文件的上传

    MySQL安全性指南

    MySQL两项性能的基本测试浅谈

    教您使用UniqueIdentifier选取SQL Server主键

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。