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]
Avete controllato tutti i certificati nella catena (in particolare, i certificati CA)? – Bruno
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
Ottieni qualcosa di più preciso quando usi '-Djavax.net.debug = all'? – Bruno