gpt4 book ai didi

java - 用于启用 HPKP 的 Tomcat 过滤器

转载 作者:行者123 更新时间:2023-11-28 22:33:43 24 4
gpt4 key购买 nike

我正在尝试在我们应用的 tomcat 服务器中启用 HPKP 证书固定。我添加了一个过滤器以包含 HSTS 和 HPKP 指令。我按预期在响应 header 中获取了 HSTS 和 HPKP 指令。

但即使在我更改服务器中的证书或拦截请求并发送假证书后,浏览器也不会停止请求。浏览器支持 HPKP,因为当请求被拦截并使用伪造的证书时,它会阻止其他启用 HPKP 的站点(如 facebook)。

只是想知道我生成公钥哈希的方式是否有任何问题,因此浏览器没有固定 key ?有没有给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

最佳答案

HTTP 的公钥固定扩展 (HPKP) 是一项安全功能,它告诉网络客户端将特定的加密公钥与特定的网络服务器相关联,以降低使用伪造证书进行 MITM 攻击的风险。

很遗憾,Apache Tomcat 不支持 HPKP 过滤器。所以我们必须编写自己的“全局过滤器”Valve。首先,您需要从您的证书或 key 文件中提取公钥信息,并使用 Base64 对它们进行编码。以下命令将帮助您从 key 文件、证书签名请求或证书中提取 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 header

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 声明 pin-sha256="M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE="也固定备份 key 。 max-age=5184000 告诉客户端将此信息存储两个月,根据 IETF RFC,这是一个合理的时间限制。此键固定对所有子域也有效,这由 includeSubDomains 声明告知。最后,report-uri="https://www.example.net/hpkp-report"解释了在哪里报告 pin 验证失败。现在创建一个 Valve,如下所述。创建 Maven Java 应用程序。添加以下依赖项:

<dependency>  
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
  • 创建您的 Java 类并从 ValveBase 扩展它。
  • 实现 invoke(Request, Response) 方法。

    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) 文件

  • 复制 ${tomcat.home}/lib 目录下的 jar 文件。
  • 配置 server.xml 以使用您的新阀门。例如:
<valve className="org.devan.GlobalFilterValve"/>
  • 启动服务器以查看您的新阀门的运行情况

谢谢!

关于java - 用于启用 HPKP 的 Tomcat 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39425175/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com