我正在尝试在我们的应用程序的tomcat服务器中启用HPKP证书固定。我添加了一个过滤器来包含HSTS和HPKP指令。我按预期在响应头中获取HSTS和HPKP指令。
但即使我在服务器中更改证书或拦截请求并发送假证书,浏览器也不会停止请求。浏览器具有HPKP功能,因为当拦截请求并提供假证书时,它会阻止其他支持HPKP的网站,如facebook。
只是想知道我生成公钥哈希的方式是否有什么问题,因此浏览器没有固定密钥?如果有人为tomcat启用了HPKP,那还有任何反馈吗?
在web.xml中添加过滤器
<filter>
<filter-name>HttpsSecFilter</filter-name>
<filter-class>com.x.x.x.x.x.HttpsSecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpsSecFilter</filter-name>
<url-pattern>..[url-pattern]..</url-pattern>
</filter-mapping>
过滤代码(为简洁而修改为仅包含相关部分)
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 && response instanceof HttpServletResponse) {
((HttpServletResponse) response).setHeader("Strict-Transport-Security",
"max-age=" + _httsMaxAge);
}
if (_isHPKPEnabled && 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) {
;
}
}
}
}
响应标题中的指令
Public-Key-Pins:pin-sha256="JdZ3itf02UwsCav0X26wcSQLGfo="; max-age=5184000
Strict-Transport-Security:max-age=5184000
答案 0 :(得分:0)
HTTP的公钥固定扩展(HPKP)是一种安全功能,它告诉Web客户端将特定加密公钥与某个Web服务器相关联,以降低使用伪造证书进行MITM攻击的风险。
不幸的是,Apache Tomcat不支持HPKP过滤器。所以我们必须编写自己的'全局过滤器',Valve。 首先,您需要从证书或密钥文件中提取公钥信息,并使用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 =”固定服务器在生产中使用的公钥。第二个引脚声明引脚-sha256 =“M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE =”也固定备份密钥。 max-age = 5184000告诉客户端将此信息存储两个月,根据IETF RFC,这是一个合理的时间限制。此密钥固定也适用于所有子域,includeSubDomains声明告知该子域。最后,report-uri =“https://www.example.net/hpkp-report”解释了报告引脚验证失败的位置。 现在创建一个Valve,如下所述。 创建Maven Java应用程序。 添加以下依赖项:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
实现调用(请求,响应)方法。
public class GlobalFilterValve extends ValveBase {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
response.setHeader("Public-Key-Pins", "pin-sha256=\"cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=\"; pin-sha256=\"M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=\"; max-age=5184000; includeSubDomains");
getNext().invoke(request, response);
}
}
构建您的库(.jar)文件
<valve className="org.devan.GlobalFilterValve"/>
谢谢!
答案 1 :(得分:-1)
尝试更新/etc/apache2/sites-enabled/website.conf
或/etc/apache2/httpd.conf
Header set Public-Key-Pins "pin-sha256=\"JdZ3itf02UwsCav0X26wcSQLGfo=\"; max-age=5184000; includeSubDomains