如何禁用Java6中的约束检查(Netscape cert类型)? [英] How to disable constraint check (Netscape cert type) in Java6?

查看:1096
本文介绍了如何禁用Java6中的约束检查(Netscape cert类型)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to build a custom HTTPS Server in Java (6) using the built in class com.sun.net.httpserver.HttpsServer. It works fine until I require client authentication. At that point it fails with the following exception in the SSL debug on the server.

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

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

I am using certificates issued by our internal CA which is used for all applications internal to us. I checked the certificate details and found that type was "SSL Server" (details quoted below). Since our policy is to use a "SSL Server" type for all internal applications, it is difficult to change the cerificate. Since I want to use a Server certificate for Client, I don't believe this is a security issue.

我想找的是一种方式禁用此约束检查Java。有没有人遇到这个和解决这个?任何帮助是高度赞赏。

What I am looking for is a way disable this constraint check in Java. Has anyone encountered this and solved this? Any help is highly appreciated.

最好的问候,
Arun

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

]


推荐答案

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

You could wrap the default trust managers and catch this particular exception. This would be something along these lines:

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 并将其与您的服务器一起使用。

Then, use that trust manager to create an SSLContext and use it with your server.

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

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

You should initialise your keymanagers from your server keystores (as normal). You should then be able to use the HttpsServer's HttpsConfigurator to set up the SSLContext (see example in the documentation).

这种技术不太理想。


  • 首先, ValidatorException 位于 sun。* 公共API:此代码将专用于Oracle / OpenJDK JRE。

  • 其次,它依赖于结束实体检查(验证密钥使用扩展)发生在信任验证的其余部分之后(这使忽略该异常成为可以接受,因为您

  • Firstly, ValidatorException is in a sun.* package that's not part of the public API: this code will be specific for the Oracle/OpenJDK JRE.
  • Secondly, it relies on the fact that the end entity checked (which verifies the key usage extension) happens after the rest of the trust validation (which makes it acceptable to ignore that exception, since you don't ignore other more fundamental checks this way).

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

You could of course re-implement your own validation instead, using the Java Certificate Path API, and ignoring only the key usage for this purpose. This requires a bit more code.

更广泛地说,如果您想使用SSL / TLS的证书作为客户端证书,您试图绕过规范当它没有正确的扩展。最好的解决方法是修改您的CA策略,如果它是一个内部CA,应该是可行的。对于服务器证书来说,即使对于大型CA,也要设置TLS客户端扩展密钥,这是很常见的。

More generally, you're trying to bypass the specifications anyway, if you want to use a certificate for SSL/TLS as a client certificate when it doesn't have the right extension. The best fix for this is to amend your CA policy, which should be feasible if it's an internal CA anyway. It's quite common for server certificates to have the TLS client extended key usage set too, even with big CAs.

这篇关于如何禁用Java6中的约束检查(Netscape cert类型)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆