Aru*_*run 5 java ssl certificate jsse x509
我正在尝试使用内置类com.sun.net.httpserver.HttpsServer在Java(6)中构建自定义HTTPS服务器.它工作正常,直到我需要客户端身份验证 此时,它在服务器上的SSL调试中失败并出现以下异常.
sun.security.validator.ValidatorException:Netscape证书类型不允许用于SSL客户端
我使用的是内部CA颁发的证书,用于我们内部的所有应用程序.我查看了证书详细信息,发现该类型是"SSL Server"(详情请参阅下文).由于我们的政策是对所有内部应用程序使用"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#.
]
]
Run Code Online (Sandbox Code Playgroud)
您可以包装默认的信任管理器并捕获此特定异常。这将是这样的:
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
}
Run Code Online (Sandbox Code Playgroud)
然后,使用该信任管理器创建一个信任管理器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);
Run Code Online (Sandbox Code Playgroud)
您应该从服务器密钥库初始化密钥管理器(正常情况下)。然后您应该能够使用HttpsServer来HttpsConfigurator设置SSLContext(请参阅文档中的示例)。
但这种技术并不理想。
ValidatorException中:此代码将特定于 Oracle/OpenJDK JRE。sun.*当然,您可以使用 Java 证书路径 API 重新实现您自己的验证,并仅忽略用于此目的的密钥用法。这需要更多的代码。
更一般地说,如果您想在没有正确扩展名的情况下使用 SSL/TLS 证书作为客户端证书,那么您无论如何都会尝试绕过规范。解决此问题的最佳方法是修改您的 CA 策略,如果它是内部 CA,那么这应该是可行的。服务器证书也设置 TLS 客户端扩展密钥使用是很常见的,即使对于大型 CA 也是如此。
| 归档时间: |
|
| 查看次数: |
5071 次 |
| 最近记录: |