V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sparanoid
V2EX  ›  SSL

为 HTTPS 网站开启 HPKP( Public Key Pinning)

  •  
  •   sparanoid · 2015-10-13 21:49:38 +08:00 · 6115 次点击
    这是一个创建于 3362 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在折腾 HPKP ,总结一下

    介绍

    HPKP 简单说就是在 HTTP 头中定义一组 Base64 编码的 SPKI 指纹,在支持 HPKP 的浏览器中,浏览器会先对比 HTTP 头中的 SPKI 指纹与当前证书的的实际指纹,从而可以一定程度上防止伪造证书的中间人攻击,更多请参考 https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning

    语法

    Public-Key-Pins: pin-sha256="base64=="; max-age=expireTime [; includeSubdomains][; report-uri="reportURI"]
    

    要点

    • pin-sha256 至少要有两个,第一个必须在当前证书链中,后面的作为备份证书,必须不在当前的证书链中,也就是说你可以在后面的 pin 中用完全不存在的指纹,但会有安全隐患
    • 你也可以 pin 中继链,这样就不用每次换证书的时候都换指纹,但如果你的 CA 的证书不是很难搞到的话这样也会有隐患(如有错误请指教)
    • 如果需要更换 SSL 证书,需要在定义的 max-age 之前就将新证书的指纹放入备用 pin 中

    指纹生成方法

    # RSA key
    $ openssl rsa -in my.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
    
    # ECDSA (例如 COMODO ECC )
    $ openssl ec -in my.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
    

    Nginx 设置

    add_header Public-Key-Pins 'pin-sha256="ABCD"; pin-sha256="EFGI"; max-age=86400';
    

    测试

    Chrome 中打开 chrome://net-internals/#hsts ,然后请求( query )当前域名后,如果设置正确的话会看到类似下面的结果:

    dynamic_sts_domain: ci.sparanoid.com
    dynamic_upgrade_mode: STRICT
    dynamic_sts_include_subdomains: true
    dynamic_sts_observed: 1443522549.33342
    dynamic_pkp_domain: ci.sparanoid.com
    dynamic_pkp_include_subdomains: true
    dynamic_pkp_observed: 1443522549.333427
    dynamic_spki_hashes: sha256/6X0iNAQtPIjXKEVcqZBwyMcRwq1yW60549axatu3oDE=,sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=
    

    Firefox 可以在 Web Inspector 的 Network 标签查看

    Qualys SSL Labs 可以在测试结果中看到(例子

    HPKP Reporting

    当浏览器检测到指纹不匹配时,可以 POST 请求到一个制定的地址,这里推荐使用 RequestBin 进行调试:

    add_header Public-Key-Pins-Report-Only 'pin-sha256="FAKE"; pin-sha256="EFGI"; max-age=86400; report-uri="http://requestb.in/onk0wkon"';
    

    目前只有 Chrome 46 支持 Public-Key-Pins-Report-Only

    第 1 条附言  ·  2015-11-22 00:24:08 +08:00
    发现一个专注于 HPKP 和 CSP 的服务: https://report-uri.io/
    8 条回复    2015-12-06 20:49:38 +08:00
    xfspace
        1
    xfspace  
       2015-10-13 22:10:30 +08:00
    然而...这些新功能特性,大公司并没用上。
    sparanoid
        2
    sparanoid  
    MOD
    OP
       2015-10-13 22:30:14 +08:00 via iPhone
    @xfspace 然而 Google 、 GitHub 都用上了 :)
    c742435
        3
    c742435  
       2015-10-13 23:08:55 +08:00
    @sparanoid 然而用上了是不是就没办法用 fiddler 调试了
    xfspace
        4
    xfspace  
       2015-10-14 01:40:16 +08:00 via Android
    @sparanoid 国内的...国外的恨不得你用新的东西,兼容旧版本是多么痛苦!
    lenovo
        5
    lenovo  
       2015-10-21 16:41:12 +08:00
    @sparanoid 请问备份的 pin-sha256 怎么生成?谢谢
    sparanoid
        6
    sparanoid  
    MOD
    OP
       2015-10-21 18:51:34 +08:00 via iPhone
    @lenovo 生成方法和第一个 pin 一样,用备用证书生成就可以了
    lenovo
        7
    lenovo  
       2015-10-21 22:40:27 +08:00
    @sparanoid 多谢,用之前过期的证书生成了一个:)
    ahu
        8
    ahu  
       2015-12-06 20:49:38 +08:00
    Generating the SPKI Fingerprint 有 3 种方法:

    Given the public key pub.key:

    openssl rsa -pubout -in pub.key -outform der | \
    openssl dgst -sha256 -binary | \
    base64
    Given the CSR my.csr:

    openssl req -noout -in my.csr -pubkey | \
    openssl rsa -pubin -outform der | \
    openssl dgst -sha256 -binary | \
    base64
    Or given the PEM-encoded certificate certificate.pem:

    openssl x509 -noout -in certificate.pem -pubkey | \
    openssl rsa -pubin -outform der | \
    openssl dgst -sha256 -binary | \
    base64
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1001 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:52 · PVG 05:52 · LAX 13:52 · JFK 16:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.