Class HpkpHeaderWriter
- All Implemented Interfaces:
HeaderWriter
Since Section 4.1 states
that a value on the order of 60 days (5,184,000 seconds) may be considered a good
balance, we use this value as the default. This can be customized using
setMaxAgeInSeconds(long)
.
Because Appendix B
recommends that operators should first deploy public key pinning by using the
report-only mode, we opted to use this mode as default. This can be customized using
setReportOnly(boolean)
.
Since we need to validate a certificate chain, the "Public-Key-Pins" or
"Public-Key-Pins-Report-Only" header will only be added when
ServletRequest.isSecure()
returns true
.
To set the pins you first need to extract the public key information from your certificate or key file and encode them using Base64. The following commands will help you extract the Base64 encoded information from a key file, a certificate signing request, or a certificate.
openssl rsa -in my-key-file.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64 openssl req -in my-signing-request.csr -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 openssl x509 -in my-certificate.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64The following command will extract the Base64 encoded information for a website.
openssl s_client -servername www.example.com -connect www.example.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Some examples:
Public-Key-Pins: max-age=3000; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" Public-Key-Pins: max-age=5184000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=" Public-Key-Pins: max-age=5184000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; report-uri="https://example.com/pkp-report" Public-Key-Pins-Report-Only: max-age=5184000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; report-uri="https://other.example.net/pkp-report" Public-Key-Pins: max-age=5184000; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; includeSubDomains
- Since:
- 4.1
-
Constructor Summary
ConstructorDescriptionCreates a new instanceHpkpHeaderWriter
(long maxAgeInSeconds) Creates a new instanceHpkpHeaderWriter
(long maxAgeInSeconds, boolean includeSubDomains) Creates a new instanceHpkpHeaderWriter
(long maxAgeInSeconds, boolean includeSubDomains, boolean reportOnly) Creates a new instance -
Method Summary
Modifier and TypeMethodDescriptionvoid
addSha256Pins
(String... pins) Adds a list of SHA256 hashed pins for the pin- directive of the Public-Key-Pins header.void
setIncludeSubDomains
(boolean includeSubDomains) If true, the pinning policy applies to this pinned host as well as any subdomains of the host's domain name.void
setMaxAgeInSeconds
(long maxAgeInSeconds) Sets the value (in seconds) for the max-age directive of the Public-Key-Pins header.void
Sets the value for the pin- directive of the Public-Key-Pins header.void
setReportOnly
(boolean reportOnly) To get a Public-Key-Pins header you should set this to false, otherwise the header will be Public-Key-Pins-Report-Only.void
setReportUri
(String reportUri) Sets the URI to which the browser should report pin validation failures.void
setReportUri
(URI reportUri) Sets the URI to which the browser should report pin validation failures.void
writeHeaders
(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) Create aHeader
instance.
-
Constructor Details
-
HpkpHeaderWriter
public HpkpHeaderWriter(long maxAgeInSeconds, boolean includeSubDomains, boolean reportOnly) Creates a new instance- Parameters:
maxAgeInSeconds
- maps tosetMaxAgeInSeconds(long)
includeSubDomains
- maps tosetIncludeSubDomains(boolean)
reportOnly
- maps tosetReportOnly(boolean)
-
HpkpHeaderWriter
public HpkpHeaderWriter(long maxAgeInSeconds, boolean includeSubDomains) Creates a new instance- Parameters:
maxAgeInSeconds
- maps tosetMaxAgeInSeconds(long)
includeSubDomains
- maps tosetIncludeSubDomains(boolean)
-
HpkpHeaderWriter
public HpkpHeaderWriter(long maxAgeInSeconds) Creates a new instance- Parameters:
maxAgeInSeconds
- maps tosetMaxAgeInSeconds(long)
-
HpkpHeaderWriter
public HpkpHeaderWriter()Creates a new instance
-
-
Method Details
-
writeHeaders
public void writeHeaders(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) Description copied from interface:HeaderWriter
Create aHeader
instance.- Specified by:
writeHeaders
in interfaceHeaderWriter
- Parameters:
request
- the requestresponse
- the response
-
setPins
Sets the value for the pin- directive of the Public-Key-Pins header.
The pin directive specifies a way for web host operators to indicate a cryptographic identity that should be bound to a given web host. See Section 2.1.1 for additional details.
To get a pin of Public-Key-Pins: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" Use
Map<String, String> pins = new HashMap<String, String>(); pins.put("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "sha256"); pins.put("E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=", "sha256");
- Parameters:
pins
- the map of base64-encoded SPKI fingerprint & cryptographic hash algorithm pairs.- Throws:
IllegalArgumentException
- if pins is null
-
addSha256Pins
Adds a list of SHA256 hashed pins for the pin- directive of the Public-Key-Pins header.
The pin directive specifies a way for web host operators to indicate a cryptographic identity that should be bound to a given web host. See Section 2.1.1 for additional details.
To get a pin of Public-Key-Pins-Report-Only: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" Use HpkpHeaderWriter hpkpHeaderWriter = new HpkpHeaderWriter(); hpkpHeaderWriter.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=");
- Parameters:
pins
- a list of base64-encoded SPKI fingerprints.- Throws:
IllegalArgumentException
- if a pin is null
-
setMaxAgeInSeconds
public void setMaxAgeInSeconds(long maxAgeInSeconds) Sets the value (in seconds) for the max-age directive of the Public-Key-Pins header. The default is 60 days.
This instructs browsers how long they should regard the host (from whom the message was received) as a known pinned host. See Section 2.1.2 for additional details.
To get a header like Public-Key-Pins-Report-Only: max-age=2592000; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" Use HpkpHeaderWriter hpkpHeaderWriter = new HpkpHeaderWriter(); hpkpHeaderWriter.setMaxAgeInSeconds(TimeUnit.DAYS.toSeconds(30));
- Parameters:
maxAgeInSeconds
- the maximum amount of time (in seconds) to regard the host as a known pinned host. (i.e. TimeUnit.DAYS.toSeconds(30) would set this to 30 days)- Throws:
IllegalArgumentException
- if maxAgeInSeconds is negative
-
setIncludeSubDomains
public void setIncludeSubDomains(boolean includeSubDomains) If true, the pinning policy applies to this pinned host as well as any subdomains of the host's domain name. The default is false.
See Section 2.1.3 for additional details.
To get a header like Public-Key-Pins-Report-Only: max-age=5184000; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; includeSubDomains you should set this to true.
- Parameters:
includeSubDomains
- true to include subdomains, else false
-
setReportOnly
public void setReportOnly(boolean reportOnly) To get a Public-Key-Pins header you should set this to false, otherwise the header will be Public-Key-Pins-Report-Only. When in report-only mode, the browser should not terminate the connection with the server. By default this is true.
See Section 2.1 for additional details.
To get a header like Public-Key-Pins: max-age=5184000; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" you should the this to false.
- Parameters:
reportOnly
- true to report only, else false
-
setReportUri
Sets the URI to which the browser should report pin validation failures.
See Section 2.1.4 for additional details.
To get a header like Public-Key-Pins-Report-Only: max-age=5184000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; report-uri="https://other.example.net/pkp-report" Use HpkpHeaderWriter hpkpHeaderWriter = new HpkpHeaderWriter(); hpkpHeaderWriter.setReportUri(new URI("https://other.example.net/pkp-report"));
- Parameters:
reportUri
- the URI where the browser should send the report to.
-
setReportUri
Sets the URI to which the browser should report pin validation failures.
See Section 2.1.4 for additional details.
To get a header like Public-Key-Pins-Report-Only: max-age=5184000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; report-uri="https://other.example.net/pkp-report" Use HpkpHeaderWriter hpkpHeaderWriter = new HpkpHeaderWriter(); hpkpHeaderWriter.setReportUri("https://other.example.net/pkp-report");
- Parameters:
reportUri
- the URI where the browser should send the report to.- Throws:
IllegalArgumentException
- if the reportUri is not a valid URI
-