Consumir Servicio web bajo Https en JavaUnofficial Content
 
Importar el certificado y manejo del almacén de certificado (keystore) en Java.
 
Este proceso consta de dos etapas: 
 
1)      Guardar el certificado del servidor en un keystore
2)      Consumir el web service indicándole a la aplicación dónde está el keystore con el certificado.
 

1)      Guardando el certificado del servidor en un keystore

 
En primera instancia, es necesario esclarecer que para poder comunicarse con un recurso bajo https es necesario tener instalado el certificado del servidor con el cual nos queremos comunicar. Este certificado contiene la clave pública con la cual se encripta la información que se envía y que solo el servidor sabe desencriptar con su clave privada (más información aquí). Por lo tanto, a la hora de consumir un servicio bajo https necesitaremos el certificado del servidor para poder establecer la comunicación.
 
Una vez que obtenemos el certificado debemos guardarlo en un keystore. Un keystore es básicamente un "almacén de certificados" que nos permite agregar nuevos certificados o eliminarlos (entre otras cosas). Una manera de manipular/administrar estos keystores es mediante la herramienta "Keytool.exe" que trae el JDK.
 
En resumen, lo anterior se reduce a 2 pasos simples:
 

1.1)   Obtener el certificado

 
Con el IExplorer ir al servidor del cual quiero obtener su certificado (https://www.dominio.com/webservice). Luego ir a File->Properties->Certificates. Allí en 'Details' ir por 'Copy to File...' y elegir por ejemplo 'Base-64 encoded X.509'. Con esto se guarda el certificado en un archivo.
 
Web service seguro/autenticación - wsdl certificado
  

 1.2)   Agregar el certificado en un keystore

 
Agregamos el certificado (ej) "certif.cer" en el keystore MiKeystore:
 
C:\>"c:\Program Files\Java\jdk1.5.0_05\bin\keytool.exe" -import -file certif.cer -keystore c:\MiKeystore -storepass MiPassword
  

2)     Configurar el keystore creado, en la aplicación java (en el trustore de Java) 

 
2.1)       En Aplicaciones java command line 

Cumplidos los pasos anteriores solo queda indicarle a la aplicación la ubicación del keystore para que al momento de establecer la comunicación sepa de donde tomar el certificado. Para esto se deben configurar las "system properties": javax.net.ssl.trustStore y  javax.net.ssl.trustStorePassword. Algo que se hace comúnmente es agregar dichas propiedades en la instancia de la máquina virtual lo cual se puede hacer en las Interpreter Options de GX si la aplicación es win o agregando estas entradas a las java options del tomcat si la aplicación es web.
 
En caso contrario se pueden configurar por código agregando las siguientes líneas en la rutina que consume el servicio (o en cualquier otra parte de la aplicación que se ejecute antes de consumir el servicio):
 
java System.setProperty("javax.net.ssl.trustStore", "C:\\MiKeystore");
java System.setProperty("javax.net.ssl.trustStorePassword", "MiPassword");
 

2.2)       En Aplicaciones java Web con Tomcat

Se siguen los mismos pasos para guardar el certificado, con la diferencia de que no se configura el trustore con un keystore propio (Mykeystore) sino que se  debe incluir en el keystore del tomcat ubicado en %JAVA_HOME%\lib\security\cacerts
Para incluir se utiliza el siguiente comando: 
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
Por ejemplo: C:\Program Files\Java\jre1.8.0_51\bin>keytool -import -noprompt -trustcacerts -alias fortigate -file   C:\mykeystore\fortigateinf.cer -keystore ..\lib\security\cacerts
Para listar y verificar si se agregó el cetificado usar la siguiente sentencia: keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
OBS: la contraseña por defecto del keystore es changeit
Luego hay que configurar el trustore con dicho keystore, para eso hay dos opciones
a. A nivel de la aplicación, embeber en el código genexus
java System.setProperty("javax.net.ssl.trustStore", "C:\\...\\jre\\lib\\security\\cacerts");
java System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
 
b. la otra opción es agregar las siguientes propiedades en el Tomcat:
 
-Djavax.net.ssl.trustStore= %JAVA_HOME%\lib\security\cacerts
-Djavax.net.ssl.trustStorePassword=changeit
 
i2015_08_12_18_18_301_png
 
Despues de esto reinicar el webserver ( Tomcat ) 
 
IMPORTANTE: En algun caso puede suceder que de el error siguiente en la invocación del webservice:

javax.net.ssl.SSLException:
Connection has been shutdown:
avax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to findvalid certification path to requested target

Solución: Es porque se recorrió toda la jerarquía de los archivos .cer pero no encontró una Autoridad Certificadora en la que se pueda confiar. Es decir, el certificado, fue firmado por una firma en la cual no se confia (es decir, no esta en el keystore). En ese caso, ver todos los certificados del sitio, y agregarlos todos al keystore, usando una alias distinto para cada caso (opcion -alias de la opcion -import)
Por ejemplo si el certif.cer, tiene alguna referencia a otro certificado (Doble Click con el .cer y alli Certification Path, hay un arbol con varios certificados), se debe bajar cada uno de esos certificados (.cer)  y ejecutar un comando keytool. similar al anterior, cambiando el alias, para cada archvio. Algo como:  

keytool -import -noprompt -trustcacerts -alias certif2 -file certif2.cer -keystore "C:\Program Files (x86)\Java\jre1.8.0_91\lib\security\cacerts" -storepass changeit
 

3)    En caso de ser necesario, configurar un certificado del cliente (pfx) (en el keystore de Java) 

hay caso en los cuales se necesita enviar un certificado desde el cliente, un certificado con clave privada (.pfx). Para ello hay que hacer:

3.1)Importar el certificado del cliente en un nuevo keystore haciendo:

keytool.exe -importkeystore -destkeystore <nombreKeyStore> -srckeystore <ruta archivo pfx>\archivo.pfx -srcstoretype pkcs12 -deststoretype JKS -srcstorepass <password>

El keystore no puede ser el mismo que el del trustStore.
Luego es necesario que la password del certificado sea la misma que la password del nuevo keystore.

 
Si la password del certificado cumple con ciertas reglas minimas de seguridad (tener más de 6 dígitos) , se puede crear el nuevo keystore con la misma password del certificado 
En caso contrario, sera necesario cambiar el password del certificado del cliente, para que coincida con la del KeyStore
Para cambiar la password del certificado : 

Para saber cual es el alias del certificado hay que hacer esto: 
keytool.exe -list -v -keystore <nombreKeyStore>
 
Para cambiar el password:
keytool.exe -keypasswd -alias <alias> -keystore <nombreKeyStore>
 

3.2)  Configurar el Keystore de Java con el Keystore creado 

Para eso hay dos opciones
a. A nivel de la aplicación, embeber en el código genexus

java System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
java System.setProperty("javax.net.ssl.keyStore", "
C:\\ClientCertificate\\cacerts2");
java System.setProperty("javax.net.ssl.keyStorePassword", "Password");

b. La otra opción es agregar la siguientes propiedades en el tomcat:

-Dsun.security.ssl.allowUnsafeRenegotiation=true 

-Djavax.net.ssl.keyStore=C:\ClientCertificate\cacerts2 
-Djavax.net.ssl.keyStorePassword=changeit2 
-Djavax.net.ssl.keyStoreType=JKS