Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 密钥使用不允许数字签名_Java_Ssl_X509certificate_Digital Signature - Fatal编程技术网

Java 密钥使用不允许数字签名

Java 密钥使用不允许数字签名,java,ssl,x509certificate,digital-signature,Java,Ssl,X509certificate,Digital Signature,我正在尝试将HTTPS请求从Java EE程序发送到需要证书身份验证的主机。我有一个合适的密钥库文件,truststore和导入的CA,这两个文件的列表都显示证书在里面 但我收到以下错误: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: KeyUsage does not allow digital signatures at ... ... Caused by: sun.

我正在尝试将HTTPS请求从Java EE程序发送到需要证书身份验证的主机。我有一个合适的密钥库文件,truststore和导入的CA,这两个文件的列表都显示证书在里面

但我收到以下错误:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: KeyUsage does not allow digital signatures
    at ...

...

Caused by: sun.security.validator.ValidatorException: KeyUsage does not allow digital signatures
    at sun.security.validator.EndEntityChecker.checkTLSServer(EndEntityChecker.java:270)
    at sun.security.validator.EndEntityChecker.check(EndEntityChecker.java:141)
    at sun.security.validator.Validator.validate(Validator.java:264)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at     sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1319)
... 29 more
查看扩展部分中的证书内容,我会看到以下内容:

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 33 87 72 1D 09 2F DF FF   1A A7 D1 C0 E1 CF C5 FA  3.r../..........
0010: A4 19 54 2E                                        ..T.
]
]

#2: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
   SSL client
]

#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 74 9F 43 07 CC 75 FA D3   D0 13 0F 65 36 CC 4A 9A  t.C..u.....e6.J.
0010: E0 8E 9C 52                                        ...R
]
]

#4: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://test.az:7447/Test%20CA.crl]
]]

#5: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
]
private final static int KU_SIGNATURE = 0;

...

private void checkTLSServer(X509Certificate cert, String parameter)
        throws CertificateException {
    Set<String> exts = getCriticalExtensions(cert);

    ...

    } else if (KU_SERVER_SIGNATURE.contains(parameter)) {
        if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
            throw new ValidatorException
                    ("KeyUsage does not allow digital signatures",
                    ValidatorException.T_EE_EXTENSIONS, cert);
        }
    }

    ...
}
因此,我的证书确实包含KeyUsage[DigitalSignature]

引发异常的位置的代码段如下所示:

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 33 87 72 1D 09 2F DF FF   1A A7 D1 C0 E1 CF C5 FA  3.r../..........
0010: A4 19 54 2E                                        ..T.
]
]

#2: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
   SSL client
]

#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 74 9F 43 07 CC 75 FA D3   D0 13 0F 65 36 CC 4A 9A  t.C..u.....e6.J.
0010: E0 8E 9C 52                                        ...R
]
]

#4: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://test.az:7447/Test%20CA.crl]
]]

#5: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
]
private final static int KU_SIGNATURE = 0;

...

private void checkTLSServer(X509Certificate cert, String parameter)
        throws CertificateException {
    Set<String> exts = getCriticalExtensions(cert);

    ...

    } else if (KU_SERVER_SIGNATURE.contains(parameter)) {
        if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
            throw new ValidatorException
                    ("KeyUsage does not allow digital signatures",
                    ValidatorException.T_EE_EXTENSIONS, cert);
        }
    }

    ...
}
返回(keyUsage.length>bit)和&keyUsage[bit]失败


问题是为什么上面表达式的结果=false?当bit=0且cert.getKeyUsage()必须返回布尔值[true、false、false、false、false、false、false]数组时,

错误实际上来自验证服务器的证书。该证书的密钥使用部分不包含数字签名位


一些密码套件需要数字签名位,特别是Diffie-Hellman密钥交换(DHE_RSA和ECDHE_RSA)。您可以通过避免这些密码类型来避免此错误。否则服务器证书需要支持它。

这个错误也发生在我身上,@Chris D的答案是正确的,我想给你一个解决这个问题的方法

我们的Java应用程序必须通过HTTPS与服务器通信。如果我们能够调整此服务器的TLS,我们就可以解决这个问题

基本上,我们需要在HTTPS服务器上禁用所有基于Diffie Hellman的密码。您需要排除所有包含
DH
的密码

对于Haproxy,我使用了以下指令:

global
    ssl-default-bind-ciphers AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
对于Java HTTPS服务器,我设置了以下环境变量:

SERVER_SSL_CIPHERS=TLS_RSA_WITH_AES_128_GCM_SHA256:TLS_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_128_CBC_SHA256:TLS_RSA_WITH_AES_256_CBC_SHA256:TLS_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA
然后将其转换为Java属性



如果您想在客户端强制执行一些密码,那么这个问题可能是您在寻找什么

是否检查了链中的所有证书(特别是CA证书)?是的,事实上我使用的是运行JRE6的旧服务器上的密钥库和信任库,并且没有问题,但是JRE7的新版本抛出了上述异常。当使用
-Djavax.net.debug=all
时,您是否得到了更精确的信息?您到底使用了Java 7的哪个版本?抱歉,问题有点错,编辑了页脚。如何避免在Java中使用这些密码?