目录搜索
GuidesAccess control CORSAuthenticationBrowser detection using the user agentCachingCaching FAQCompressionConditional requestsConnection management in HTTP 1.xContent negotiationContent negotiation: List of default Accept valuesCookiesCSPMessagesOverviewProtocol upgrade mechanismProxy servers and tunnelingProxy servers and tunneling: Proxy Auto-Configuration (PAC) filePublic Key PinningRange requestsRedirectionsResources and specificationsResources and URIsResponse codesServer-Side Access ControlSessionGuides: BasicsBasics of HTTPChoosing between www and non-www URLsData URIsEvolution of HTTPIdentifying resources on the WebMIME TypesMIME types: Complete list of MIME typesCSPContent-Security-PolicyContent-Security-Policy-Report-OnlyCSP: base-uriCSP: block-all-mixed-contentCSP: child-srcCSP: connect-srcCSP: default-srcCSP: font-srcCSP: form-actionCSP: frame-ancestorsCSP: frame-srcCSP: img-srcCSP: manifest-srcCSP: media-srcCSP: object-srcCSP: plugin-typesCSP: referrerCSP: report-uriCSP: require-sri-forCSP: sandboxCSP: script-srcCSP: style-srcCSP: upgrade-insecure-requestsCSP: worker-srcHeadersAcceptAccept-CharsetAccept-EncodingAccept-LanguageAccept-RangesAccess-Control-Allow-CredentialsAccess-Control-Allow-HeadersAccess-Control-Allow-MethodsAccess-Control-Allow-OriginAccess-Control-Expose-HeadersAccess-Control-Max-AgeAccess-Control-Request-HeadersAccess-Control-Request-MethodAgeAllowAuthorizationCache-ControlConnectionContent-DispositionContent-EncodingContent-LanguageContent-LengthContent-LocationContent-RangeContent-TypeCookieCookie2DateDNTETagExpectExpiresForwardedFromHeadersHostIf-MatchIf-Modified-SinceIf-None-MatchIf-RangeIf-Unmodified-SinceKeep-AliveLarge-AllocationLast-ModifiedLocationOriginPragmaProxy-AuthenticateProxy-AuthorizationPublic-Key-PinsPublic-Key-Pins-Report-OnlyRangeRefererReferrer-PolicyRetry-AfterServerSet-CookieSet-Cookie2SourceMapStrict-Transport-SecurityTETkTrailerTransfer-EncodingUpgrade-Insecure-RequestsUser-AgentUser-Agent: FirefoxVaryViaWarningWWW-AuthenticateX-Content-Type-OptionsX-DNS-Prefetch-ControlX-Forwarded-ForX-Forwarded-HostX-Forwarded-ProtoX-Frame-OptionsX-XSS-ProtectionMethodsCONNECTDELETEGETHEADMethodsOPTIONSPATCHPOSTPUTStatus100 Continue101 Switching Protocols200 OK201 Created202 Accepted203 Non-Authoritative Information204 No Content205 Reset Content206 Partial Content300 Multiple Choices301 Moved Permanently302 Found303 See Other304 Not Modified307 Temporary Redirect308 Permanent Redirect400 Bad Request401 Unauthorized403 Forbidden404 Not Found405 Method Not Allowed406 Not Acceptable407 Proxy Authentication Required408 Request Timeout409 Conflict410 Gone411 Length Required412 Precondition Failed413 Payload Too Large414 URI Too Long415 Unsupported Media Type416 Range Not Satisfiable417 Expectation Failed426 Upgrade Required428 Precondition Required429 Too Many Requests431 Request Header Fields Too Large451 Unavailable For Legal Reasons500 Internal Server Error501 Not Implemented502 Bad Gateway503 Service Unavailable504 Gateway Timeout505 HTTP Version Not Supported511 Network Authentication RequiredStatus
文字

公共密钥钢钉扩展HTTP(HPKP)是一种安全功能,它讲述了一个Web客户端与某个web服务器的特定密码公钥关联到降低风险中间人伪造证书的攻击。

为了确保在TLS会话中使用的服务器公钥的真实性,该公钥被封装到通常由证书颁发机构(CA)签署的X.509证书中。Web客户端(如浏览器)信任很多这些CA,它们都可以为任意域名创建证书。如果攻击者能够危害单个CA,他们可以对各种TLS连接执行MITM攻击。HPKP可以通过告诉客户端哪个公钥属于某个Web服务器来规避HTTPS协议的这种威胁。

HPKP是首次使用信托(TOFU)技术。Web服务器第一次通过特殊的HTTP头告诉客户端公钥属于它,客户端将这些信息存储一段给定的时间。当客户端再次访问服务器时,它期望证书链中至少有一个证书包含已通过HPKP识别指纹的公钥。如果服务器提供未知的公钥,则客户端应向用户提供警告。

Firefox和Chrome 禁用了针对经过验证的证书链终止于用户定义的信任锚(而不是内置信任锚)的固定主机的引脚验证。这意味着对于导入自定义根证书的用户,所有钉住违规都会被忽略。

启用HPKP

要为您的站点启用此功能,您需要在Public-Key-Pins通过HTTPS访问站点时返回HTTP标头:

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

pin-sha256引用的字符串是Base64编码的主题公钥信息(SPKI)指纹。可以为不同的公钥指定多个引脚。未来某些浏览器可能会允许其他哈希算法而不是SHA-256。请参阅下面有关如何从证书或密钥文件中提取此信息。max-age以秒为单位的浏览器应该记住,该站点只能使用其中一个定义的键来访问。includeSubDomains可选如果指定了此可选参数,则此规则也适用于所有网站的子域。report-uri可选如果指定了此可选参数,则将引脚验证失败报告给给定的URL。

注意:目前的规范要求包含一个备用密钥的第二个引脚,该密钥尚未用于生产。这允许更改服务器的公钥,而不会破坏已经注意到引脚的客户端的可访问性。例如,当前一个密钥受到攻击时,这很重要。

提取Base64编码的公钥信息

注意:虽然下面的示例显示了如何在服务器证书上设置管脚,但建议将管脚放置在颁发服务器证书的CA的中间证书上,以简化证书更新和轮换。

首先,您需要从证书或密钥文件中提取公钥信息并使用Base64对其进行编码。

以下命令将帮助您从密钥文件,证书签名请求或证书中提取Base64编码的信息。

openssl rsa -in my-rsa-key-file.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
openssl ec -in my-ecc-key-file.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
openssl req -in my-signing-request.csr -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
openssl x509 -in my-certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

以下命令将提取网站的Base64编码信息。

openssl s_client -servername www.example.com -connect www.example.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

示例HPKP标题

Public-Key-Pins: 
  pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; 
  pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="; 
  max-age=5184000; includeSubDomains; 
  report-uri="https://www.example.org/hpkp-report"

在本例中,pin-sha256 =“cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2 + soZS7sWs =”固定生产中使用的服务器公钥。第二个引脚声明pin-sha256 =“M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE =”也引脚备份密钥。max-age = 5184000告诉客户将这些信息存储两个月,根据IETF RFC这是一个合理的时间限制。此关键固定也适用于所有子域,这由includeSubDomains声明告知。最后,report-uri =“ https://www.example.net/hpkp-report解释报告引脚验证失败的位置。

仅限报告的标题

Public-Key-Pins您也可以使用Public-Key-Pins-Report-Only标题,而不是使用标题。此标题仅将报告发送到report-uri标题中指定的报告,并且仍允许浏览器连接到Web服务器,即使违反了固定也是如此。

设置您的网络服务器以包含HPKP标题

提供HPKP头文件所需的具体步骤取决于您使用的Web服务器。

注意:这些示例使用两个月的最大年龄并包含所有子域。建议验证此设置适用于您的服务器。

如果使用不当,HPKP可能会长时间锁定用户!建议使用备份证书和/或固定CA证书。

阿帕奇

在您的web服务器的配置文件中添加一行类似于以下内容的行将启用Apache上的HPKP。这需要mod_headers启用。

Header always set Public-Key-Pins "pin-sha256=\"base64+primary==\"; pin-sha256=\"base64+backup==\"; max-age=5184000; includeSubDomains"

Nginx的

添加以下行并插入适当的pin-sha256="..."值将在您的nginx上启用HPKP。这需要ngx_http_headers_module.

add_header Public-Key-Pins 'pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubDomains' always;

Lighttpd

以下与相关密钥信息(pin-sha256 =“...”字段)的行将启用lighttpd上的HPKP。

setenv.add-response-header  = ( "Public-Key-Pins" => "pin-sha256=\"base64+primary==\"; pin-sha256=\"base64+backup==\"; max-age=5184000; includeSubDomains")

注意:这需要mod_setenv加载server.module,如果尚未加载,可以将其包含在内。

server.modules += ( "mod_setenv" )

IIS

将以下行添加到Web.config文件以发送Public-Key-Pins标头:

<system.webServer>  ...  <httpProtocol>    <customHeaders>      <add name="Public-Key-Pins" value="pin-sha256=&quot;base64+primary==&quot;; pin-sha256=&quot;base64+backup==&quot;; max-age=5184000; includeSubDomains" />    </customHeaders>  </httpProtocol>  ...</system.webServer>

产品规格

规范

标题

RFC 7469,第2.1节:公钥索引

HTTP的公钥固定扩展

浏览器兼容性

Feature

Chrome

Edge

Firefox

Internet Explorer

Opera

Safari

Basic Support

(Yes)

No1

35.0

?

(Yes)

?

report-uri

46

?

No2

?

33

?

Feature

Android

Chrome for Android

Edge mobile

Firefox for Android

IE mobile

Opera Android

iOS Safari

Basic Support

(Yes)

(Yes)

?

35.0

?

(Yes)

?

report-uri

(Yes)

(Yes)

?

No

?

33

?

上一篇:下一篇: