utiliza servicio recomienda que propietario migrar instalar formato crear convertir consumir cliente claves certificado bajo autenticación almacén ssl java-7 smartcard pkcs#11 authentication

ssl - servicio - que es un keystore



Autenticación de cliente SSL con tarjeta inteligente funciona en Java 6 pero falla en Java 7 (1)

el siguiente código crea un contexto SSL autenticado por el cliente usando el dispositivo PKCS # 11 (tarjeta inteligente). Todo funciona muy bien con Java 6:

// Configure the SunPkcs11 provider String pkcs11config; pkcs11config = "name = Cryptoki"; pkcs11config += "/nlibrary = /SCDriver/libbit4ipki.dylib"; InputStream confStream = new ByteArrayInputStream(pkcs11config.getBytes()); SunPKCS11 sunpkcs11 = new SunPKCS11(confStream); Security.addProvider(sunpkcs11); // Specify keystore builder parameters for PKCS#11 keystores Builder scBuilder = Builder.newInstance("PKCS11", sunpkcs11, new KeyStore.CallbackHandlerProtection(new PasswordRetriever())); // Create and init KeyManagerFactory KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509"); factory.init(new KeyStoreBuilderParameters(scBuilder)); // create and init ssl context m_ssl_context = SSLContext.getInstance("TLS"); m_ssl_context.init(factory.getKeyManagers(), new TrustManager[] {new PkTrustManager()}, null); SSLContext.setDefault(m_ssl_context);

El PkTrustManager es una clase simple y ''vacía'', que toma cualquier certificado de servidor / cliente para siempre, y PasswordRetriever simplemente solicita una contraseña a través de un cuadro de diálogo (Por solicitud publico el código fuente para estos). En Java 7, en cambio, recibo la siguiente excepción durante el protocolo de enlace SSL del contexto ssl:

java.security.InvalidKeyException: Class does not represent an RSA key: sun.security.pkcs11.P11Key$P11PrivateKey at iaik.pkcs.pkcs1.RSACipher.engineInit(Unknown Source) at iaik.pkcs.pkcs1.RSACipher.engineInit(Unknown Source) at iaik.security.rsa.RSA.init(Unknown Source) at iaik.security.rsa.RawRSASignature.engineInitSign(Unknown Source) at java.security.SignatureSpi.engineInitSign(SignatureSpi.java:103) at java.security.Signature.initSign(Signature.java:529) at sun.security.ssl.RSASignature.engineInitSign(RSASignature.java:125) at java.security.Signature$Delegate.engineInitSign(Signature.java:1136) at java.security.Signature.initSign(Signature.java:529) at sun.security.ssl.HandshakeMessage$CertificateVerify.<init>(HandshakeMessage.java:1556) at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:982) ... 14 more

En el mejor de los casos, diría que algo ha cambiado en la parte interna de Java, pero al revisar la documentación de Oracle, no encontré ningún supuesto cambio en el administrador de claves NewSunX509 u otros componentes. Comprobé dos veces el código y parece cumplir con las especificaciones (¡a través de eso seguro que algo me perdí!).

Traté de agregar los indicadores de configuración:

System.setProperty("javax.net.ssl.keyStoreType", "pkcs11"); System.setProperty("javax.net.ssl.keyStore", "NONE"); System.setProperty("javax.net.ssl.trustStoreType", "pkcs11"); System.setProperty("javax.net.ssl.trustStore", "NONE"); System.setProperty("javax.net.ssl.keyStoreProvider", sunpkcs11.getName() ); JCEMapper.setProviderId(sunpkcs11.getName());

Pero no hay cambio, el mismo error ... y no son necesarios en Java 6 donde todo funciona. ¡Gracias de antemano que cualquiera puede ayudar o tiene alguna idea!

PD: a pedido de @owlstead agregó -Djava.security.debug = sunpkcs11 y obtuvo el siguiente resultado:

SunPKCS11 loading ---DummyConfig-1--- sunpkcs11: Initializing PKCS#11 library /SCDriver/libbit4ipki.dylib Information for provider SunPKCS11-Cryptoki Library info: cryptokiVersion: 2.20 manufacturerID: bit4id srl flags: 0 libraryDescription: bit4id PKCS#11 libraryVersion: 1.02 All slots: 0 Slots with tokens: 0 Slot info for slot 0: slotDescription: bit4id miniLector-U38 00 00 manufacturerID: unknown flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT hardwareVersion: 0.00 firmwareVersion: 0.00 Token info for token in slot 0: label: CNS manufacturerID: ST Incard model: CNS (LB) serialNumber: 7420057800291590 flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED ulMaxSessionCount: CK_EFFECTIVELY_INFINITE ulSessionCount: 0 ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE ulRwSessionCount: CK_UNAVAILABLE_INFORMATION ulMaxPinLen: 8 ulMinPinLen: 5 ulTotalPublicMemory: 31988 ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION ulTotalPrivateMemory: 780 ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION hardwareVersion: 0.00 firmwareVersion: 0.00 utcTime: 0000000000000000 Mechanism CKM_RSA_PKCS: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2561 = CKF_HW | CKF_DECRYPT | CKF_SIGN Mechanism CKM_RSA_PKCS_KEY_PAIR_GEN: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 65537 = CKF_HW | CKF_GENERATE_KEY_PAIR Mechanism CKM_SHA1_RSA_PKCS: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2049 = CKF_HW | CKF_SIGN Mechanism CKM_SHA_1: ulMinKeySize: 0 ulMaxKeySize: 0 flags: 1024 = CKF_DIGEST Mechanism CKM_SHA256: ulMinKeySize: 0 ulMaxKeySize: 0 flags: 1024 = CKF_DIGEST Mechanism CKM_SHA256_RSA_PKCS: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2049 = CKF_HW | CKF_SIGN Mechanism CKM_SHA384: ulMinKeySize: 0 ulMaxKeySize: 0 flags: 1024 = CKF_DIGEST Mechanism CKM_SHA384_RSA_PKCS: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2049 = CKF_HW | CKF_SIGN Mechanism CKM_SHA512: ulMinKeySize: 0 ulMaxKeySize: 0 flags: 1024 = CKF_DIGEST Mechanism CKM_SHA512_RSA_PKCS: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2049 = CKF_HW | CKF_SIGN Mechanism CKM_RSA_X_509: ulMinKeySize: 1024 ulMaxKeySize: 1024 flags: 2561 = CKF_HW | CKF_DECRYPT | CKF_SIGN Password per token PKCS11 [SunPKCS11-Cryptoki]: sunpkcs11: login succeeded sunpkcs11: user already logged in javax.net.ssl.SSLHandshakeException: Error signing certificate verify at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) *....... (continues with the exception as described above)*

Nota: con la última actualización de Java 6, mi código también deja de funcionar en Java 6 :(


Resuelto agregando la línea de código:

Security.removeProvider("IAIK");

antes de la línea:

Security.addProvider(sunpkcs11);

Esto funciona correctamente con todas las versiones de java6 y java7 (esperando que no vuelvan a atornillar algo en java8 ... :)

Parece que el proveedor IAIK se inserta a sí mismo como un proveedor PKCS11 pero luego realiza llamadas a la clave privada usándola como una clave de software ... porque en realidad es un proveedor de software.