Informazioni sui provider di sicurezza Java

2

Spero di utilizzare il problema riportato di seguito che ci siamo imbattuti recentemente per comprendere meglio i provider di sicurezza, i codici e la crittografia di Java in generale.

Abbiamo ricevuto il seguente errore durante un handshake SSL (utilizzando InstallCert strumento) da un host Solaris 10, che esegue Java 1.6.0_81 in uno dei due host AD:

]$ java InstallCert host1.example.com:636 
Loading KeyStore /usr/jdk/instances/jdk1.6.0/jre/lib/security/cacerts...
Opening connection to host1.example.com:636...
Starting SSL handshake...

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not parse key values
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1708)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1691)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1222)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
        at InstallCert.main(InstallCert.java:98)
Caused by: java.lang.RuntimeException: Could not parse key values
        at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:954)
        at sun.security.pkcs11.P11Key$P11ECPublicKey.getW(P11Key.java:975)
        at com.sun.net.ssl.internal.ssl.ECDHClientKeyExchange.<init>(ECDHClientKeyExchange.java:40)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:782)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:241)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:943)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
        ... 2 more
Caused by: java.io.IOException: extra data given to DerValue constructor
        at sun.security.util.DerValue.init(DerValue.java:368)
        at sun.security.util.DerValue.<init>(DerValue.java:277)
        at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:945)
        ... 11 more

Il secondo host non fornisce errori. L'unica differenza che sono riuscito a spigolare qui è la cifra su host1.example.com - è AES256-SHA; il cipher su host2.example.com è AES128-SHA.

]$ echo -n | openssl s_client -connect host1.example.com:636 | grep 'Cipher is'
New, TLSv1/SSLv3, Cipher is AES256-SHA

]$ echo -n | openssl s_client -connect host2.example.com:636 | grep 'Cipher is'
New, TLSv1/SSLv3, Cipher is AES128-SHA

Le mie domande sono:

  • Qual è lo scopo dei provider di sicurezza Java e qual è il loro ruolo nella crittografia?
  • Di cosa si tratta della cifra di AES256-SHA su host1.example.com che produce questo errore?
  • Alla fine abbiamo commentato questo fornitore di sicurezza in java.security file per risolvere il problema:

    security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/sunpkcs11-solaris.cfg

Quindi sembra che questa combinazione di un provider bug e di Cipher abbia causato questo problema? Quel collegamento fa riferimento a "EC" e non sono sicuro di cosa sia.

Qualche suggerimento e approfondimento molto apprezzato!

    
posta KM. 26.11.2014 - 15:41
fonte

2 risposte

1

E in particolare ECDH è la variante curva ellittica di Diffie-Hellman, usata qui per lo scambio di chiavi. Quasi certamente sotto forma di ECDHE, effimero ECDH, ma non possiamo confermarlo dalle informazioni qui.

Non puoi dire "il" codice sul server; praticamente tutte le implementazioni SSL / TLS supportano più ciphersuites (abbreviate, imprecisamente, cifrari). Normalmente il client offre una grande lista di suite supportate dal client, e il server sceglie la "migliore" tra quelle supportate dal server, dove esattamente ciò che è "migliore" è complicato e ci sono (molte) altre domande su quello . Anche se mi ass-u-me AD significa Windows Active Directory, non so quali suite supporta e credo che dipenda dalle tue versioni di Windows e possibilmente da AD né di quelle che hai dichiarato.

Il tuo tentativo di Java6 di host1 ha chiaramente offerto almeno una suite utilizzando ECDH che il server ha scelto, ma che non ha funzionato nel provider Sun PKCS11. Non sono sicuro di Solaris, ma le distribuzioni Java6 di Windows e Linux di Sun non includevano un provider ECC integrato e quindi non offrirebbero (o concorderebbero) alcuna suite ECDH a meno che PKCS11 non dia accesso a qualcosa che (presumibilmente) supportava. Java7 e 8 do vengono forniti con ECC integrato, ma se si ha PKCS11 nella posizione 1 del provider, otterrà comunque la preferenza.

La tua openssl s_client ha negoziato una suite RSA semplice su host1. (Il nome OpenSSL AES256-SHA significa in realtà TLS_RSA_WITH_AES_256_CBC_SHA, per ragioni storiche i nomi OpenSSL omettono la RSA per lo scambio di chiavi plain-RSA.) Le versioni OpenSSL 0.9. * Non supportano ECC di default e produrranno questo risultato. (Tecnicamente puoi ottenere 0.9.8 per fare ECC se lo batti abbastanza, ma presumo che tu ne abbia parlato.) OpenSSL (upstream) 1.0.0 o versione successiva supporta tutte le suite ECDH standard e le preferisce , che mi aspetto di far selezionare al server. Conosco i pacchetti RedHat di OpenSSL omessi ECC fino a poco tempo fa per problemi di brevetto; ovviamente RedHat non si applica a Solaris, ma probabilmente il packager (a?) di Solaris avrebbe potuto fare la stessa cosa. È anche possibile che qualcuno abbia ottimizzato la build per supportare ECC ma non preferirlo, e il server ha seguito questa preferenza. Potresti provare ad aggiungere -cipher ECDH:!aNULL e vedere se riesce a ottenere qualche suite ECDH e in tal caso quale.

Fidarsi selvaggiamente con Java: In ogni caso, con openssl non hai bisogno di InstallCert . Fare

echo Q | openssl s_client -connect $host:$port -showcerts \
| nawk '/--BEG/,/--END/{print>"anchor"} /--END/{close("anchor")}'

vale a dire. aggiungi -showcerts e seleziona il blocco ultimo dei dati del certificato in un file, quindi

 keytool -keystore $YOURJRE/lib/security/cacerts -importcert -file anchor -alias $NAME

dove $NAME è un breve nome di lettere e cifre solo mnemonico della tua autorità locale (dominio o altro), e inserisci la password changeit e conferma.

    
risposta data 29.01.2015 - 14:27
fonte
0

What is the purpose of Java security providers and what is their role in encryption?

Estratto dal mio file jdk / jre / lib / security / java.security:

#
# This is the "master security properties file".
#
# In this file, various security properties are set for use by
# java.security classes. This is where users can statically register
# Cryptography Package Providers ("providers" for short). The term
# "provider" refers to a package or set of packages that supply a
# concrete implementation of a subset of the cryptography aspects of
# the Java Security API. A provider may, for example, implement one or
# more digital signature algorithms or message digest algorithms.
#
# Each provider must implement a subclass of the Provider class.
# To register a provider in this master security properties file,
# specify the Provider subclass name and priority in the format
#
#    security.provider.<n>=<className>
#
# This declares a provider, and specifies its preference
# order n. The preference order is the order in which providers are
# searched for requested algorithms (when no specific provider is
# requested). The order is 1-based; 1 is the most preferred, followed
# by 2, and so on.
#
# <className> must specify the subclass of the Provider class whose
# constructor sets the values of various properties that are required
# for the Java Security API to look up the algorithms or other
# facilities implemented by the provider.
#
# There must be at least one provider specification in java.security.
# There is a default provider that comes standard with the JDK. It
# is called the "SUN" provider, and its Provider subclass
# named Sun appears in the sun.security.provider package. Thus, the
# "SUN" provider is registered via the following:
#
#    security.provider.1=sun.security.provider.Sun
#
# (The number 1 is used for the default provider.)
#
# Note: Providers can be dynamically registered instead by calls to
# either the addProvider or insertProviderAt method in the Security
# class.

[Modificato] Modificherò la mia risposta alla sola domanda a cui sono qualificato per rispondere qui, cedendo alla risposta di dave_thompson in merito alla causa del bug.

    
risposta data 28.01.2015 - 19:59
fonte

Leggi altre domande sui tag