【问题标题】:How to disable constraint check (Netscape cert type) in Java6?如何在 Java6 中禁用约束检查(Netscape 证书类型)?
【发布时间】:2012-09-15 05:33:47
【问题描述】:

我正在尝试使用内置类 com.sun.net.httpserver.HttpsServer 在 Java (6) 中构建自定义 HTTPS 服务器。在我需要客户端身份验证之前它工作正常。此时,它在服务器上的 SSL 调试中失败并出现以下异常。

sun.security.validator.ValidatorException:Netscape 证书类型不允许用于 SSL 客户端

我正在使用我们内部 CA 颁发的证书,该证书用于我们内部的所有应用程序。我检查了证书详细信息,发现类型是“SSL 服务器”(下面引用了详细信息)。由于我们的政策是对所有内部应用程序使用“SSL 服务器”类型,因此很难更改证书。由于我想为客户端使用服务器证书,我不认为这是一个安全问题。

我正在寻找的是一种在 Java 中禁用此约束检查的方法。有没有人遇到过这个并解决了这个?非常感谢任何帮助。

最好的问候, 阿伦

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#.
]

]

【问题讨论】:

    标签: java ssl certificate x509 jsse


    【解决方案1】:

    您可以包装默认信任管理器并捕获此特定异常。这将是这样的:

    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
    }        
    

    然后,使用该信任管理器创建一个 SSLContext 并将其用于您的服务器。

    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);
    

    您应该从您的服务器密钥库中初始化您的密钥管理器(正常)。然后,您应该能够使用HttpsServerHttpsConfigurator 来设置SSLContext(参见文档中的示例)。

    不过,这种技术并不理想。

    • 首先,ValidatorException 位于不属于公共 API 的 sun.* 包中:此代码将特定于 Oracle/OpenJDK JRE。
    • 其次,它依赖于最终实体检查(验证密钥使用扩展)happens after the rest of the trust validation(这使得忽略该异常是可以接受的,因为您不会以这种方式忽略其他更基本的检查)。

    您当然可以改用 Java 证书路径 API 重新实现自己的验证,并为此目的只忽略密钥用法。这需要更多代码。

    更一般地说,如果您想在没有正确扩展名的情况下使用 SSL/TLS 证书作为客户端证书,则无论如何您都在尝试绕过规范。解决此问题的最佳方法是修改您的 CA 策略,如果它是内部 CA,这应该是可行的。服务器证书也设置了 TLS 客户端扩展密钥使用设置是很常见的,即使是大型 CA。

    【讨论】:

    • 非常感谢。它工作得很好。我同意理想的解决方案是更新 CA 策略,但如果我不构建绕过解决方案,我的软件在数百个系统上的升级将需要立即更新证书。
    • 这听起来像是一个肮脏的修复,将持续到永远。
    • @sjas 是的,我只是希望读到这篇文章的人能读懂正文,不要简单地复制粘贴。
    猜你喜欢
    • 2020-02-12
    • 1970-01-01
    • 2012-06-12
    • 2019-03-03
    • 2017-03-03
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多