2016-09-10 76 views
1

我試圖在我們的應用程序的tomcat服務器中啓用HPKP證書鎖定。我添加了一個過濾器來包含HSTS和HPKP指令。按照預期,我在響應頭中獲得了HSTS和HPKP指令。用於啓用HPKP的Tomcat篩選器

但即使在我更改服務器中的證書或攔截請求併發送假證書後,瀏覽器也不會停止請求。瀏覽器具有HPKP功能,因爲當請求被攔截並顯示假證書時,它會阻止其他啓用了HPKP的網站(如Facebook)。

只是想知道是否有什麼錯誤的方式我生成公鑰的散列,因此瀏覽器不鎖住鑰匙?任何反饋如果任何人已啓用HPKP的tomcat?

過濾器在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 

回答

-1

嘗試更新/etc/apache2/sites-enabled/website.conf/etc/apache2/httpd.conf

Header set Public-Key-Pins "pin-sha256=\"JdZ3itf02UwsCav0X26wcSQLGfo=\"; max-age=5184000; includeSubDomains 
+0

他問tomcat不是apache2 –

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" 

在這個例子中,在生產中使用的銷-SHA256 = 「cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2 + soZS7sWs =」 引腳的服務器的公共密鑰。第二個引腳聲明pin-sha256 =「M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE =」也引腳備份密鑰。 max-age = 5184000告訴客戶將這些信息存儲兩個月,根據IETF RFC這是一個合理的時間限制。此關鍵固定也適用於所有子域,這由includeSubDomains聲明告知。最後,report-uri =「https://www.example.net/hpkp-report」說明報告引腳驗證失敗的位置。 現在創建一個閥門,如下所述。 創建一個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 jar文件/ lib目錄下。
  • 配置server.xml以使用您的新閥門。例如:
<valve className="org.devan.GlobalFilterValve"/> 
  • 啓動服務器,看看你的新閥動作

謝謝!