Entendiendo los proveedores de seguridad de Java

2

Espero utilizar el problema a continuación que encontramos recientemente para comprender mejor los proveedores de seguridad, cifrado y cifrado de Java en general.

Obtuvimos el siguiente error durante un protocolo de enlace SSL (usando InstallCert tool) desde un host Solaris 10, ejecutando Java 1.6.0_81 a uno de los dos hosts 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

El segundo host no da ningún error. La única diferencia que he podido adivinar aquí es el cifrado en host1.example.com : es AES256-SHA; el cifrado en host2.example.com es 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

Mis preguntas son:

  • ¿Cuál es el propósito de los proveedores de seguridad de Java y cuál es su función en el cifrado?
  • ¿De qué se trata el cifrado de AES256-SHA en host1.example.com que produce este error?
  • Finalmente, comentamos este proveedor de seguridad en el archivo java.security para resolver el problema:

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

¿Parece que esta combinación de un proveedor con errores y Cipher estaba causando este problema? Ese enlace hace referencia a "EC", y no estoy seguro de qué es eso.

Cualquier punteros y puntos de vista muy apreciados!

    
pregunta KM. 26.11.2014 - 15:41
fuente

2 respuestas

1

Y, más específicamente, ECDH es la variante de curva elíptica de Diffie-Hellman, utilizada aquí para el intercambio de claves. Casi con toda seguridad en la forma de ECDHE, efímero ECDH, pero no podemos confirmarlo a partir de la información que se encuentra aquí.

No puede decir "el" cifrado en el servidor; prácticamente todas las implementaciones de SSL / TLS son compatibles con múltiples conjuntos de cifrado (abreviados, imprecisamente, cifrados). Normalmente, el cliente ofrece una gran lista de suites que admite, y el servidor elige la "mejor" entre las que también admite el servidor, donde exactamente lo que es "mejor" es complicado y hay (muchas) otras preguntas al respecto. . Incluso si Ass-u-me AD significa Active Directory de Windows, no sé qué suites son compatibles y creo que depende de sus versiones de Windows y posiblemente de AD que ninguna de las dos haya indicado.

Su intento de Java6 de host1 ofreció claramente al menos una suite con ECDH que eligió el servidor, pero que no funcionó en el proveedor de Sun PKCS11. No estoy seguro de Solaris, pero las distribuciones Java y Windows de Linux de Sun no incluían un proveedor de ECC integrado y, por lo tanto, no ofrecerían (o aceptarían) ninguna suite de ECDH a menos que PKCS11 dé acceso a algo que (supuestamente) lo respaldaba. Java7 y 8 do vienen con ECC incorporado, pero si tiene PKCS11 en la posición 1 del proveedor, seguirá teniendo preferencia.

Su openssl s_client negoció un conjunto simple de RSA en host1. (El nombre de OpenSSL AES256-SHA en realidad significa TLS_RSA_WITH_AES_256_CBC_SHA; por razones históricas, los nombres de OpenSSL omiten el RSA para el intercambio de claves simple-RSA). Las versiones OpenSSL 0.9. * No son compatibles con ECC por defecto y producirían este resultado. (Técnicamente, puedes obtener 0.9.8 para hacer ECC si lo superas lo suficiente, pero supongo que lo habrías mencionado). OpenSSL (upstream) 1.0.0 o superior es compatible con todas las suites estándar de ECDH y las prefiere , que esperaría hacer que el servidor seleccione uno. Sé que los paquetes RedHat de OpenSSL omitieron ECC hasta hace poco por cuestiones de patentes; obviamente, RedHat no se aplicaría en Solaris, pero posiblemente el (¿un?) empaquetador de Solaris podría haber hecho lo mismo. También es posible que alguien haya modificado tu compilación para que sea compatible con ECC pero no la prefiera, y el servidor siguió esa preferencia. Puede intentar agregar -cipher ECDH:!aNULL y ver si eso logra obtener alguna suite ECDH y, en caso afirmativo, cuál.

Confiando enormemente en Java: En cualquier caso, con openssl no necesitas InstallCert . Hacer

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

es decir, agregue -showcerts y seleccione el último bloque de datos de certificado en un archivo, luego

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

donde $NAME es un nombre breve de letras y dígitos solo mnemotécnico de su autoridad local (dominio o lo que sea), ingrese la contraseña changeit y confirme.

    
respondido por el dave_thompson_085 29.01.2015 - 14:27
fuente
0
  

¿Cuál es el propósito de los proveedores de seguridad de Java y cuál es su función?   en cifrado?

Extracto de mi archivo 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.

[EDITADO] Enmendaré mi respuesta a la única pregunta que estoy calificado para responder aquí, y cederé a la respuesta de dave_thompson en lo que respecta a la causa del error.

    
respondido por el avgvstvs 28.01.2015 - 19:59
fuente

Lea otras preguntas en las etiquetas