2013-03-12 4 views
5

Я пытаюсь отправить HTTPS-запрос из моей программы Java EE на хост, для которого требуется аутентификация сертификата. У меня есть правильный файл хранилища ключей, truststore с импортированным CA, список обоих показывает, что сертификаты находятся внутри.KeyUsage не разрешает цифровые подписи

Но я получаю следующее сообщение об ошибке:

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 
] 

Так что мой сертификат действительно содержит 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); 
     } 
    } 

    ... 
} 

и checkKeyUsage функции:

private boolean checkKeyUsage(X509Certificate cert, int bit) 
     throws CertificateException { 
    boolean[] keyUsage = cert.getKeyUsage(); 
    if (keyUsage == null) { 
     return true; 
    } 
    return (keyUsage.length > bit) && keyUsage[bit]; 
} 

он терпит неудачу в возвращения (keyUsage.length> бит) & & keyUsage [бит];

Вопрос в том, почему результат вышеуказанного выражения = false? Когда бит = 0 и cert.getKeyUsage() должен возвращать массив логических значений [true, false, false, false, false, false, false, false, false]

+0

Вы проверили все сертификаты в цепочке (в частности, сертификаты CA)? – Bruno

+0

Да, на самом деле я использую хранилище ключей и доверенное хранилище с моего старого сервера, который запускает JRE6, и на нем нет никаких проблем, но новый с JRE7 выдает выше исключения. – chaplean

+0

Получаете ли вы что-нибудь более точное при использовании '-Djavax.net.debug = all'? – Bruno

ответ

6

Ошибка на самом деле происходит от проверки сертификата сервера. У этого сертификата есть ключевой раздел использования, который не включает бит digitalSignature.

Для некоторых наборов шифров требуется бит цифровой подписи, в частности обмен ключами Диффи-Хеллмана (DHE_RSA и ECDHE_RSA). Вы можете избежать этой ошибки, избегая этих типов шифров. В противном случае сертификат сервера должен поддерживать его.

+2

И как избежать использования этих шифров из java? –

Смежные вопросы