2012-09-23 29 views
5

Tôi đang cố gắng xây dựng một Máy chủ HTTPS tùy chỉnh bằng Java (6) bằng cách sử dụng lớp built in com.sun.net.httpserver.HttpsServer. Nó hoạt động tốt cho đến khi tôi yêu cầu xác thực ứng dụng khách. Tại thời điểm đó nó không thành công với ngoại lệ sau trong gỡ lỗi SSL trên máy chủ.Làm thế nào để vô hiệu hóa kiểm tra ràng buộc (loại chứng chỉ Netscape) trong Java6?

sun.security.validator.ValidatorException: Netscape loại cert không cho phép sử dụng cho SSL client

Tôi đang sử dụng chứng chỉ do CA nội bộ của chúng tôi được sử dụng cho tất cả các ứng dụng nội bộ đối với chúng tôi. Tôi đã kiểm tra chi tiết chứng chỉ và thấy rằng loại đó là "Máy chủ SSL" (chi tiết được trích dẫn bên dưới). Vì chính sách của chúng tôi là sử dụng loại "Máy chủ SSL" cho tất cả các ứng dụng nội bộ, rất khó để thay đổi chứng chỉ. Vì tôi muốn sử dụng chứng chỉ Máy chủ cho Ứng dụng khách, tôi không tin đây là vấn đề bảo mật.

Điều tôi đang tìm kiếm là cách tắt kiểm tra ràng buộc này trong Java. Có ai gặp phải điều này và giải quyết vấn đề này không? Bất kỳ sự trợ giúp nào cũng được đánh giá cao.

Best Regards, Arun

Owner: CN=myapp, OU=mygroup, O=mycompany 

Issuer: O=MYCA 

Serial number: 4cc8c1da 

Valid from: Mon Jan 10 13:46:34 EST 2011 until: Thu Jan 10 14:16:34 EST 2013 

Certificate fingerprints: 
     MD5: 8C:84:7F:7A:40:23:F1:B5:81:CD:F9:0C:27:16:69:5E 
     SHA1: 9B:39:0B:2F:61:83:52:93:D5:58:E5:43:13:7A:8F:E1:FD:AC:98:A4 
     Signature algorithm name: SHA1withRSA 
     Version: 3 

Extensions: 

[1]: ObjectId: 2.5.29.16 Criticality=false 
PrivateKeyUsage: [ 
From: Mon Jan 10 13:46:34 EST 2011, To: Wed Jul 11 21:16:34 EDT 2012] 

[2]: ObjectId: 2.5.29.15 Criticality=false 
KeyUsage [ 
    DigitalSignature 
    Key_Encipherment 
] 

[3]: ObjectId: 2.5.29.14 Criticality=false 
SubjectKeyIdentifier [ 
KeyIdentifier [ 
0000: D3 47 35 9B B4 B7 03 18 C6 53 2C B0 FE FD 49 D8 .G5......S,...I. 
0010: D0 FB EE 15          .... 
] 
] 

[4]: ObjectId: 1.2.840.113533.7.65.0 Criticality=false 

[5]: ObjectId: 2.5.29.31 Criticality=false 
CRLDistributionPoints [ 
    [DistributionPoint: 
    [CN=CRL413, O=SWIFT] 
]] 

[6]: ObjectId: 2.5.29.19 Criticality=false 
BasicConstraints:[ 
    CA:false 
    PathLen: undefined 
] 

****[7]: ObjectId: 2.16.840.1.113730.1.1 Criticality=false 
NetscapeCertType [ 
    SSL server 
]**** 

[8]: ObjectId: 2.5.29.35 Criticality=false 
AuthorityKeyIdentifier [ 
KeyIdentifier [ 
0000: 8F AF 56 BC 80 77 A3 FD 9E D2 89 83 98 FE 98 C7 ..V..w.......... 
0010: 20 65 23 CC           e#. 
] 

] 

Trả lời

1

Bạn có thể quấn các nhà quản lý tin tưởng mặc định và bắt ngoại lệ đặc biệt này. Đây sẽ là một cái gì đó dọc theo những dòng:

class IgnoreClientUsageTrustManager extends X509TrustManager { 
    private final X509TrustManager origTrustManager; 
    public class IgnoreClientUsageTrustManager(X509TrustManager origTrustManager) { 
     this.origTrustManager = origTrustManager; 
    } 

    public checkClientTrusted(X509Certificate[] chain, String authType 
     throws IllegalArgumentException, CertificateException { 
     try { 
      this.origTrustManager.checkClientTrusted(chain, authType); 
     } catch (ValidatorException e) { 
      // Check it's that very exception, otherwise, re-throw. 
     } 
    } 

    // delegate the other methods to the origTrustManager 
}   

Sau đó, sử dụng quản lý tin tưởng để tạo ra một SSLContext và sử dụng nó với máy chủ của bạn.

TrustManagerFactory tmf = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init((KeyStore)null); 
TrustManager[] trustManagers = tmf.getTrustManagers(); 

for (int i = 0; i < trustManagers.length; i++) { 
    if (trustManagers[i] instanceof X509TrustManager) { 
     trustManagers[i] = IgnoreClientUsageTrustManager(trustManagers[i]); 
    } 
} 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(... you keymanagers ..., trustManagers, null); 

Bạn nên khởi tạo trình quản lý khóa từ các kho khóa máy chủ (như bình thường). Sau đó, bạn có thể sử dụng HttpsConfigurator của HttpsServer để thiết lập SSLContext (xem ví dụ trong tài liệu).

Kỹ thuật này không phải là lý tưởng.

  • Thứ nhất, ValidatorException là trong một gói sun.* đó không phải là một phần của API công cộng: mã này sẽ được cụ thể cho Oracle/OpenJDK JRE. Thứ hai, nó phụ thuộc vào thực tế là thực thể cuối đã kiểm tra (xác minh phần mở rộng sử dụng khóa) happens after the rest of the trust validation (làm cho nó có thể chấp nhận bỏ qua ngoại lệ đó, vì bạn không bỏ qua các kiểm tra cơ bản khác theo cách này).

Tất nhiên, bạn có thể thực hiện lại xác thực của riêng mình bằng cách sử dụng API đường dẫn chứng chỉ Java và bỏ qua chỉ sử dụng khóa cho mục đích này. Điều này đòi hỏi nhiều mã hơn một chút.

Nói chung, bạn đang cố bỏ qua các đặc điểm, nếu bạn muốn sử dụng chứng chỉ cho SSL/TLS làm chứng chỉ ứng dụng khách khi nó không có phần mở rộng phù hợp. Cách khắc phục tốt nhất cho việc này là sửa đổi chính sách CA của bạn, điều này sẽ khả thi nếu đó là CA nội bộ. Nó cũng khá phổ biến đối với các chứng chỉ máy chủ để máy khách TLS cũng mở rộng sử dụng khóa, ngay cả với các CA lớn.

+0

Cảm ơn bạn rất nhiều. Nó hoạt động rất tốt. Tôi đồng ý rằng giải pháp lý tưởng là để cập nhật chính sách CA, nhưng nếu tôi không xây dựng giải pháp bỏ qua, việc nâng cấp phần mềm của tôi lên vài trăm hệ thống sẽ yêu cầu gia hạn chứng chỉ ngay lập tức. – Arun

+2

Điều này nghe giống như một sửa chữa bẩn mà sẽ kéo dài cho tất cả vĩnh cửu và sau này. – sjas

+0

@sjas Có, tôi chỉ hy vọng rằng bất cứ ai đọc điều này đọc văn bản và không chỉ đơn giản là sao chép và dán. – Bruno

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