2013-03-12 6 views
5

Sto tentando di inviare la richiesta HTTPS dal mio programma Java EE all'host che richiede l'autenticazione del certificato. Ho un file keystore appropriato, truststore con CA importata, l'elenco di entrambi mostra che i certificati sono all'interno.KeyUsage non consente le firme digitali

Ma ricevo il seguente errore:

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 

Visualizzazione del contenuto del certificato nella parte di estensioni vedo il seguente:

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 
] 

Quindi il mio certificato contiene KeyUsage [DigitalSignature]

Lo snippet di codice del luogo che genera l'eccezione è il seguente:

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

    ... 
} 

e checkKeyUsage funzione:

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

non riesce a ritorno (keyUsage.length> bit) & & keyUsage [po];

La domanda è perché il risultato di sopra espressione = falso? Quando bit = 0 e cert.getKeyUsage() deve restituire una matrice di booleano [true, false, false, false, false, false, false, false, false]

+0

Avete controllato tutti i certificati nella catena (in particolare, i certificati CA)? – Bruno

+0

Sì, infatti utilizzo il keystore e il truststore dal mio vecchio server che esegue JRE6 e non ci sono problemi su di esso, ma il nuovo con JRE7 getta sopra l'eccezione. – chaplean

+0

Ottieni qualcosa di più preciso quando usi '-Djavax.net.debug = all'? – Bruno

risposta

6

L'errore deriva effettivamente dalla verifica del certificato del server. Questo certificato ha una sezione di utilizzo delle chiavi che non include un bit DigitalSignature.

Alcune suite di crittografia richiedono il bit della firma digitale, in particolare lo scambio di chiavi Diffie-Hellman (DHE_RSA e ECDHE_RSA). Potresti essere in grado di evitare questo errore evitando quei tipi di cifratura. Altrimenti il ​​certificato del server deve supportarlo.

+2

E come evitare di usare questi codici all'interno di java? –