viernes, noviembre 06, 2015

Consumir Servicios web con HTTPS



La conclusión que llega, con la que estoy totalmente de acuerdo, es que sí se debe usar HTTPS siempre que el usuario esté logueado y se puede usar HTTP para el contenido público. De todas formas, el costo de usar HTTPS hoy en día es muy bajo (en términos de recursos).
El protocolo HTTPS lo que hace (muy básicamenete), es encriptar la comunicación entre el servidor y el cliente, utilizando un certificado de clave pública/privada del lado del servidor. Para eso, el sitio que va a utilizar HTTPS, necesita tener un certificado válido.

Cuando un cliente se quiere conectar le pide el certificado al servidor, verifica que sea válido, y si lo es se lleva a cabo la comunicación.

La parte de "verifica que sea válido" es la más compleja, porque ambas partes tienen que confiar en alguien común, que valide el certificado, es decir, que asegure que el servidor es quien dice ser.

Para eso existen las entidades certificadoras, que tienen certificados que son de conocimiento público (porque vienen instalados con el sistema operativo o con el navegador web), y que usan para firmar los certificados de los demás sitios web.
En virtud de que muchas de las veces comaprtimos informacion muy valiosa y justamente patra evitar robo de informaciòn, se recomienda utilizar certificados, para ello describiremos una pequeña experiencia de como utilizar este nivel de seguridad en aplicaciones web especialmente en servicios web tipo REST.

Para tener una idea que es un certificado digital aprovechamos lo que existe en la WIKI: Certificado Digital.
Pero existen otros sitios donde nos explican ampliamente: Certificados Digitales


Primer paso importar el certificado del sitio:
En este caso utilizamos el GoogleChrome, pero podiamos haber utilizado cualquier navegador de tal forma que el proceso de importaciòn de certificados es muy similar, en este caso hacemos CLICK en Informacion del Certificado nos desplegara la çsiguiente pantalla:

Luego nos desplegara la siguiente pantalla:



Hacer click en SIGUIENTE, en la parte del tipo de certificado hacer click en SIGUIENTE, hasta que nos desplegue la siguiente pantalla:

Asignamos una carpeta y el nombre del certificado como nos indica la figura:



Seguidamente nos desplegarà la siguiente pantalla: 

Con esto ya disponemos del certificado y podemos continuar con la instalacion en el TOMCAT.

Cerramos el Chrome y quedamos listo para el siguiente paso que es registrar el certificado de la siguiente forma:

"c:\Program Files (x86)\Java\jdk1.6.0_45\bin\keytool.exe"      // Ubicacion de JDK
 -import -noprompt -trustcacerts                             // Parametros Fijos que significa importar y no deslegue informacion del proceso
 -alias certificado-sri                                                  // asignar un alias al certificado
 -file c:\aws\certificado-sri.cer                              // Seleccionar el certificado que recien descargamos.
 -keystore "c:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"
                                      // Adjuntamos al almacen de certificados.
 -storepass changeit                                                // Clave por omision


Ejecutamos en linea de comandos.                                      
"c:\Program Files (x86)\Java\jdk1.6.0_45\bin\keytool.exe" -import -noprompt -trustcacerts -alias certificado-sri -file c:\aws\certificado-sri.cer -keystore "c:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts" -storepass changeit  

Se debe considerar lo siguiente que la contraseña por defecto del keystore es changeit

Verificamos que el certificado conste en el almacen de certificados:
"c:\Program Files (x86)\Java\jre6\bin\keytool.exe" -list -keystore "c:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts" -storepass changeit

Como nuestra aplicacion en WEB tenemos que indicar al tomcat que hemos asignado un certificado nuevo, de la siguiente forma:

-Djavax.net.ssl.trustStore= %JAVA_HOME%jre\lib\security\cacerts
-Djavax.net.ssl.trustStorePassword=changeit



Seguidamente reiniciamos el TOMCAT y se adoptaran los cambios efectuados.

Existe el caso en los cuales se necesita tener un certificado del cliente (.pfx). Para ello hay que hacer:

Importar el certificado del cliente en el keystore haciendo:

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


Observaciones: El keystore no puede ser el mismo que el del trustStore, para ello es
recomendable cambiar el password del certificado del cliente, ya que el mismo debe cumplir ciertas reglas (tener más de 6 dígitos y además tener el mismo password que el KeyStore).
 
Para conocer cual es el alias del certificado se debe realizar lo siguiente: 

keytool.exe -list -v -keystore <nombreKeyStore>


Para cambiar el password:

keytool.exe -keypasswd -alias <alias> -keystore <nombreKeyStore>



Para que adopte el certificado el TOMCAT se debe adicionar las propiedades en el mismo:
-Dsun.security.ssl.allowUnsafeRenegotiation=true

-Djavax.net.ssl.keyStore=c:\certificados\cacerts2

-Djavax.net.ssl.keyStorePassword=changeit2

-Djavax.net.ssl.keyStoreType=JKS

Una fase interesante es citar que tambien podemos incluir en nuestro servicio web consumidor la ubicacion de los certificados, si por alguna razon no desplega mensajes de error como parte de la respuesta: 

Java and SSL - java.security.NoSuchAlgorithmException

Al utilizar el lenguaje JAVA la forma de inlcuir en la clase que consume el servicio web es la siguiente:

System.setProperty("javax.net.ssl.keyStore", "c:/Program Files (x86)/Java/jdk1.6.0_45/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", "C:/Program Files (x86)/Java/jdk1.6.0_45/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");


 
Links de referencia:
http://wiki.genexus.com/commwiki/servlet/wiki?Consumir+Servicio+web+bajo+Https+en+Java,
http://wiki.genexus.com/commwiki/servlet/wiki?Consumir+servicios+web+bajo+https+y%2Fo+autenticaci%C3%B3n,
http://blog.marcoscrispino.com/2008/10/consumir-web-service-con-ssl-y.html

Links de referencia para gestion de claves:
Gestiòn de Propiedades de Java
Informaciòn sobre KeyStore o TrustStore
Herramienta (OpenSOurce) para gestionar certificados
Otro herramienta (OpenSource) para gestionar certificados

En algun momento es necesario que se requiera conocer las propiedades del Lenguaje Java, aqui un ejemplo de como conocer dichas propiedades que pueden resultar utiles cuando llevamos a produccion una aplicacion web o win:
System.out.println("javax.net.ssl.trustStoreType--------->:" + System.getProperty("javax.net.ssl.trustStoreType"));
System.out.println("javax.net.ssl.trustStorePassword----->:" + System.getProperty("javax.net.ssl.trustStorePassword"));
System.out.println("javax.net.ssl.trustStore------------->:" + System.getProperty("javax.net.ssl.trustStore"));               
System.out.println("javax.net.ssl.keyStoreType----------->:" + System.getProperty("javax.net.ssl.keyStoreType"));
System.out.println("javax.net.ssl.keyStorePassword------->:" + System.getProperty("javax.net.ssl.keyStorePassword"));
System.out.println("javax.net.ssl.keyStore--------------->:" + System.getProperty("javax.net.ssl.keyStore"));               
System.out.println("path.separator----------------------->:" + System.getProperty("path.separator"));
System.out.println("file.separator----------------------->:" + System.getProperty("file.separator"));
System.out.println("java.class.path---------------------->:" + System.getProperty("java.class.path"));
System.out.println("java.class.version------------------->:" + System.getProperty("java.class.version"));
System.out.println("java.home---------------------------->:" + System.getProperty("java.home"));
System.out.println("java.vendor-------------------------->:" + System.getProperty("java.vendor"));
System.out.println("java.vendor.url---------------------->:" + System.getProperty("java.vendor.url"));
System.out.println("java.version------------------------->:" + System.getProperty("java.version"));
System.out.println("line.separator----------------------->:" + System.getProperty("line.separator"));
System.out.println("os.arch------------------------------>:" + System.getProperty("os.arch"));
System.out.println("os.name------------------------------>:" + System.getProperty("os.name"));
System.out.println("user.dir----------------------------->:" + System.getProperty("user.dir"));
System.out.println("user.home---------------------------->:" + System.getProperty("user.home"));
System.out.println("user.name---------------------------->:" + System.getProperty("user.name"));
                       

No hay comentarios: