[英]Migrating Tomcat from 8.0 to 8.5, Client Certificate authentication not working
我們正在將 Tomcat 服務器從 8.0 升級到 8.5。 我們的服務器應該支持 https,包括相互身份驗證、 certificateVerification
,使用 tomcat JSSE 選項的默認值。 目前似乎相互身份驗證不起作用,因為服務器無法驗證客戶端證書。
tomcat中的連接器配置如下:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true" >
<SSLHostConfig truststoreFile="/opt/allot/conf/infra.truststore" truststoreType="JKS" truststorePassword="****"
certificateVerification="required" sslProtocol="TLS" protocols="TLSv1.2,+TLSv1.1,+TLSv1.0">
<Certificate certificateKeystoreFile="/opt/allot/conf/infra.keystore"
certificateKeystoreType="JKS"
certificateKeystorePassword="****"
certificateKeyAlias="****" />
</SSLHostConfig>
</Connector>
我使用了 WireShark 嗅探器,輸出是:
No. Time Source Destination Protocol Length Info
260 5.228627 172.19.2.30 10.110.108.74 TCP 66 55710 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
261 5.230733 10.110.108.74 172.19.2.30 TCP 66 443 → 55710 [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1387 SACK_PERM=1 WS=128
262 5.230831 172.19.2.30 10.110.108.74 TCP 54 55710 → 443 [ACK] Seq=1 Ack=1 Win=131584 Len=0
263 5.252688 172.19.2.30 10.110.108.74 TLSv1.2 238 Client Hello
264 5.254772 10.110.108.74 172.19.2.30 TCP 56 443 → 55710 [ACK] Seq=1 Ack=185 Win=30336 Len=0
265 5.268445 10.110.108.74 172.19.2.30 TCP 1441 443 → 55710 [ACK] Seq=1 Ack=185 Win=30336 Len=1387 [TCP segment of a reassembled PDU]
266 5.268564 10.110.108.74 172.19.2.30 TLSv1.2 887 Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done
267 5.268607 172.19.2.30 10.110.108.74 TCP 54 55710 → 443 [ACK] Seq=185 Ack=2221 Win=131584 Len=0
268 5.329682 172.19.2.30 10.110.108.74 TLSv1.2 136 Certificate, Client Key Exchange
269 5.333364 10.110.108.74 172.19.2.30 TLSv1.2 61 Alert (Level: Fatal, Description: Bad Certificate)
270 5.333365 10.110.108.74 172.19.2.30 TCP 56 443 → 55710 [FIN, ACK] Seq=2228 Ack=267 Win=30336 Len=0
271 5.333456 172.19.2.30 10.110.108.74 TCP 54 55710 → 443 [ACK] Seq=267 Ack=2229 Win=131584 Len=0
273 5.365042 172.19.2.30 10.110.108.74 TLSv1.2 60 Change Cipher Spec
274 5.366449 10.110.108.74 172.19.2.30 TCP 56 443 → 55710 [RST] Seq=2229 Win=0 Len=0
這是我第一次使用相互認證,我很想聽聽您的建議,當然我會盡快分享解決方案。
編輯我附加了我用 java 編寫的測試客戶端,這段代碼適用於 tomcat 8.0.28 但不適用於 Tomcat 8.5.50
public static void main(String[] args) throws IOException, KeyManagementException, NoSuchAlgorithmException {
disableSslVerification();
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStore", "path/to/trustStoreFile");
System.setProperty("javax.net.ssl.trustStore", "path/to/keyStoreFile");
System.setProperty("javax.net.debug", "all");
System.setProperty("javax.net.ssl.keyStorePassword", "****");
System.setProperty("javax.net.ssl.trustStorePassword", "****");
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://10.110.108.74/webui");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setSSLSocketFactory(sslSocketFactory);
InputStream in = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(reader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
}
System.exit(0);
}
private static void disableSslVerification() throws NoSuchAlgorithmException, KeyManagementException {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
好的,我設法弄清楚了。 問題出在我們的信任庫文件中,證書是使用PrivateKeyEntry
而不是TrustedCeritciateEntry
添加的。 因此,Tomcat 服務器在沒有我們內部 CA 的情況下發送了證書請求。
回答有時會反駁的人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.