如何禁用的Java6约束检查(Netscape的证书类型)?(How to disable cons

2019-07-31 20:02发布

我想建立使用内置类com.sun.net.httpserver.HttpsServer在Java中(6)的自定义HTTPS服务器。 直到我需要客户端身份验证它工作正常。 在这一点上失败,并在服务器上的SSL调试以下异常。

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

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

我所寻找的是一个方法禁用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#.
]

]

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

你应该从你的服务器的密钥库初始化您keymanagers(正常)。 然后,您应该能够使用HttpsServerHttpsConfigurator成立SSLContext (见例如文档中)。

这种技术并不理想,虽然。

  • 首先, ValidatorException是在一个sun.*包,这不是公共API的一部分:此代码将具体针对Oracle / OpenJDK的JRE。
  • 其次,它依赖于(其中验证密钥使用扩展)的事实,终端实体检查的信任验证后剩下的发生 (这使得它可以接受忽略例外,因为你不忽略其他更基本的检查,这样)。

你当然可以重新实现自己的验证,而不是使用Java证书路径API,而忽略了只用于此目的的密钥使用。 这需要更多的代码。

更一般地,你想反正绕过规格,如果你想使用SSL / TLS证书作为客户端证书时,没有正确的扩展名。 这样做的最好的解决方法是修改您的CA政策,这应该是可行的,如果它是一个内部CA反正。 这是很常见的服务器证书有TLS客户端扩展密钥使用设得,即使有大的CA.



文章来源: How to disable constraint check (Netscape cert type) in Java6?