2016-02-06 19 views
5

Cố gắng triển khai xác thực khóa ứng dụng khách (với ca tự ký).Xác thực ứng dụng khách với HttpClient

Mã trông giống như:

KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
keyStore.load(new FileInputStream("client.p12"), "changeit".toCharArray()) 

SSLContext sslcontext = SSLContexts.custom() 
      .loadTrustMaterial(null, new TrustSelfSignedStrategy()) //DONT DO THAT, IT'S JUST TO SIMPLIFY THIS EXAMPLE. USE REAL TrustStore WITH REAL SERVER CERTIFICATE IMPORTED. DONT TRUST SELF SIGNED 
      .loadKeyMaterial(keyStore, "changeit".toCharArray()) 
      .build(); 
socketFactory = new SSLConnectionSocketFactory(
      sslcontext, 
      new String[] {"TLSv1.2", "TLSv1.1"}, 
      null, 
      new NoopHostnameVerifier() 
); 
HttpClient httpclient = HttpClients.custom() 
      .setSSLSocketFactory(socketFactory) 
      .build(); 

Với -Djavax.net.debug=all tôi có thể nhìn thấy nó một cách chính xác chọn giấy chứng nhận của tôi, tôi thấy chữ ký, tôi thấy yêu cầu chứng chỉ, và có ECDHClientKeyExchange, vv, tất cả có vẻ tốt đẹp.

Nhưng dù sao tôi nhận được câu trả lời sau đây từ Nginx (với tình trạng 400):

<head><title>400 The SSL certificate error</title></head> 

Thông báo, mà cấp giấy chứng nhận không chính xác/nginx chìa khóa thường giảm phiên, w/o cung cấp bất kỳ chi tiết để đáp ứng văn bản đơn giản .

này client.p12 công trình từ dòng lệnh, như:

$ curl -ivk --cert client.p12:changeit https://192.168.1.1 


* Rebuilt URL to: https://192.168.1.1/ 
* Trying 192.168.1.1... 
* Connected to 192.168.1.1 (192.168.1.1) port 443 (#0) 
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format. 
* Client certificate: client-es.certs.my 
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
* Server certificate: server.certs.my 
* Server certificate: ca.my 
> GET/HTTP/1.1 
> Host: 192.168.1.1 
> User-Agent: curl/7.43.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 

Vì vậy, chìa khóa này chắc chắn là hợp lệ. Nhưng tại sao nó không hoạt động cho Java? Có bất cứ điều gì tôi đã bỏ lỡ trong cấu hình java ssl?

+0

Chứng chỉ của bạn có được nhập vào kho khóa của bạn không? – STaefi

+0

nó được tải trực tiếp từ 'client.p12'. Tôi cũng đã cố gắng để nhập nó vào kho khóa, nhưng nó không thay đổi bất cứ điều gì –

Trả lời

2

Vấn đề là khóa khách hàng của tôi cũng bao gồm ký chứng chỉ trong chuỗi khóa. Không chỉ chứng chỉ khách hàng (được yêu cầu để xác thực), nhưng toàn bộ chuỗi các chứng chỉ (không có phím dĩ nhiên, chỉ cần giấy chứng nhận)

Đó là:

> Root CA cert -> Client CA cert -> Client key + cert 

Tôi đoán Java sử dụng chứng chỉ sai ở đây trường hợp, có thể là CA hoặc chứng chỉ trung gian.

Cố định bằng cách thêm p12 hoặc keychain chỉ khóa và chứng chỉ của khách hàng mà không có trung gian.

không được-certfile tùy chọn (tôi đã có trước đó). Chỉ cần khóa/cert của khách hàng. lệnh xuất khẩu đúng là:

openssl pkcs12 -export \ 
    -in client.crt -inkey client.key \ 
    -out client.p12 

client.p12 này sau đó có thể được nhập khẩu vào keychain:

keytool -importkeystore \ 
    -deststorepass changeit -destkeystore keystore \ 
    -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass changeit 

Và làm việc tốt cho xác thực tùy chỉnh.

+0

Tôi nghĩ rằng điều này đã làm với NGINX. Chúng ta có F5 và NGINX. Chúng tôi chỉ phải thực hiện thay đổi này để giao tiếp với NGINX. Tôi muốn tìm hiểu những gì tôi có thể thay đổi để NGINX sửa nó thay vì thay đổi chứng chỉ của tôi. –

Các vấn đề liên quan