Tomcat filter for enabling HPKP
<p>I am trying to enable HPKP certificate pinning in our app's tomcat server. I added a filter to include the HSTS and HPKP directives. I am getting the HSTS and HPKP directives in the response header as expected. </p>

<p>But even after I change the certificate in the server or intercept the request and send a fake certificate, browser does not stop the request. Browser is HPKP capable as it is blocking other HPKP enabled sites like facebook when the request is intercepted and presented with a fake certificate. </p>

<p>Just wondering if there is anything wrong the way I am generating the hash of the public key and hence browser is not pinning the key? Any feed back if anyone has enabled HPKP for tomcat?</p>

<p>Filter added in web.xml</p>

<pre><code>    &lt;filter&gt;
            &lt;filter-name&gt;HttpsSecFilter&lt;/filter-name&gt;
            &lt;filter-class&gt;com.x.x.x.x.x.HttpsSecurityFilter&lt;/filter-class&gt;
    &lt;/filter&gt;
    &lt;filter-mapping&gt;
            &lt;filter-name&gt;HttpsSecFilter&lt;/filter-name&gt;
            &lt;url-pattern&gt;..[url-pattern]..&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;
</code></pre>

<p>Filter code (Modified to include only relevant parts for brevity)</p>

<pre><code>public class HttpsSecurityFilter implements Filter {
    private boolean _isHTTSEnabled = false;
    private long _httsMaxAge = -1;

    private boolean _isHPKPEnabled = false;
    private long _hpkpMaxAge = -1;
    private String _hpkpCertHashesString = null;

    private boolean _includeSubdomains = false;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                FilterChain chain) throws IOException, ServletException {

        if (_isHTTSEnabled &amp;&amp; response instanceof HttpServletResponse) {
            ((HttpServletResponse) response).setHeader("Strict-Transport-Security", 
                                                       "max-age=" + _httsMaxAge);
        }

        if (_isHPKPEnabled &amp;&amp; response instanceof HttpServletResponse) {
            ((HttpServletResponse) response).setHeader("Public-Key-Pins", 
                                                       _hpkpCertHashesString);
        }

        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        //Read from application configuration file
        _isHTTSEnabled = true;
        _httsMaxAge = 5184000;

        _isHPKPEnabled = true;
        _hpkpMaxAge = 5184000;
        _includeSubdomains = false;

        if (_isHTTSEnabled) {

            try {
                KeyStore keyStore = KeyStore.getInstance("JKS");
                InputStream is = new FileInputStream(APP_HOME + "/conf/keystore");
                keyStore.load(is, keysotrePassword);
                is.close();

                Certificate cert = keyStore.getCertificate(myappcetificatealias);

                MessageDigest md = MessageDigest.getInstance("SHA-256");
                byte[] digest = md.digest(cert.getPublicKey().getEncoded());
                _hpkpCertHashesString = "pin-sha256=\"" + java.util.Base64.getEncoder()
                                        .encodeToString(digest) + "\"; max-age=" + 
                                         _hpkpMaxAge;
            } catch (Exception e) {
                ;
            }
        }
    }
}
</code></pre>

<p>Directives from response header</p>

<pre><code>Public-Key-Pins:pin-sha256="JdZ3itf02UwsCav0X26wcSQLGfo="; max-age=5184000
Strict-Transport-Security:max-age=5184000
</code></pre>