socket programming online geeks for java web-services google-app-engine ssl pki

programming - socket java online



SSL bidireccional para servicios web en GAE(java) (7)

Necesitarás la API Socket de App Engine para esto. Esta API está en modo de prueba confiable, por lo que no está disponible para todos.

Puede solicitar un acceso gere: https://docs.google.com/spreadsheet/viewform?formkey=dF9QR3pnQ2pNa0dqalViSTZoenVkcHc6MQ#gid=0

Necesitamos implementar SSL bidireccional en Google App Engine, donde enviamos solicitudes de servicio web utilizando JAX-WS a un servidor que requiere autenticación SSL bidireccional.

¿Cómo podemos configurar SSL de 2 vías para nuestras solicitudes de servicios web salientes?

Sabemos que javax.net.ssl* está prohibido en el entorno de App Engine.

Aquí hay un ejemplo de nuestro código:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl") @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) public interface ListenerSoap { @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping") public void ping(); } @WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL") public class Listener extends Service { public ListenerSoap getListenerSoap() { return super.getPort(new QName("http://example.com/Listener.Wsdl", "ListenerSoap"), ListenerSoap.class); } }

Y un ejemplo del código anterior en uso:

ListenerSoap soap = new Listener().getListenerSoap(); soap.ping();

Me imagino que podemos almacenar los almacenes de claves o cualquier certificado necesario en el DataStore como objetos binarios (aunque la forma de cargarlos sigue siendo un vago para mí).

¿Cómo podemos configurar los valores necesarios necesarios para que este servicio web se autentique utilizando SSL de 2 vías?

Gracias por cualquier ayuda

Actualizar:

A través de la investigación, he visto cómo se puede hacer en un servidor tradicional (uno con acceso al sistema de archivos):

ListenerSoap soap = new Listener().getListenerSoap(); ((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12"

Sin embargo, en este enfoque, se espera que client_cert.p12 esté en el sistema de archivos.

Además, SSLSocketFactory , SSLContext , KeyManager y KeyManagerFactory no están permitidos en GAE.

Actualizar:

A partir de la versión 1.7.7 de GAE SDK. esto debería ser posible ahora:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections.

Notas de la versión de GAE 1.7.7 SDK


Parece que hay confusión sobre la conexión simple a través de SSL ( https://... ) y lo que se conoce como "autenticación mutua" o "infraestructura de clave pública (PKI)". Realmente puedes hacer ambas cosas o una independiente de otra. Con este último (a lo que creo que se refiere la pregunta original), cuando realiza una solicitud al servidor, el servidor le responderá solicitando un certificado que debe presentar para autenticarse.

Para responder a la pregunta específica anterior (cargar un almacén de claves a partir de datos binarios), no creo que sea realmente posible, ya que es el tiempo de ejecución de Java el que recoge su almacén de claves. Lo único que podría hacer es cargar los bits de su almacén de datos y escribirlos temporalmente en el disco. Opcionalmente eliminarlo cuando exista la aplicación. Esto lo he hecho antes y funciona bastante bien. Si haces esto, te recomiendo usar una ubicación que pueda escribirse (como System.getProperty("java.io.tmpdir")); ), luego de escribir el archivo en el disco, establezca las propiedades de JVM (por ejemplo, System.getProperties().put( "javax.net.ssl.keyStore","..."); )


Por lo que sé sobre SSL bidireccional, no tendrá enlace con el código Java EE: SSL bidireccional es una seguridad de capa de transporte: cuando su aplicación cliente intentará crear una conexión HTTP segura (HTTPS) con el servidor, el servidor Solicite un certificado y aprobará o no este certificado. Si se aprueba el certificado del cliente, se establecerá una conexión segura entre las partes y se les permitirá intercambiar algunos mensajes a través de este túnel. Pero este proceso se realiza en la capa de transporte. Su código (en la capa de aplicación) nunca será informado de este proceso. Para establecer un SSL bidireccional, la configuración se realiza en la configuración del servidor de aplicaciones para el puerto SSL.


Por mi conocimiento restringido sobre la autorización SSL, parece que puede que te falte algo de vital importancia aquí; los certificados. SSL bidireccional requiere que los certificados de cliente y servidor estén en su almacén de claves, que puede ser un certificado autofirmado (un archivo pkcs12 o pem, que puede generar fácilmente con unos pocos comandos a través del shell) o un certificado de propiedad emitido por Una empresa autorizada como Thawte o Verisign. Aunque no estoy seguro de si ese es el problema al que te enfrentas, pero es bueno revisarlo. (Además, soy un novato, así que no descargues mi respuesta, solo trato de sugerir posibles opciones).


Sé que es posible que no desee escuchar esto, pero el uso de SSL es costoso y problemático para la comunicación bidireccional. Dependiendo de la cantidad de control que tenga sobre el servidor / cliente, prefiero una canalización bidireccional simple como sockets web y un protocolo de paquete de datos que simplemente puede implementar AES. Realmente depende del problema que está tratando de resolver.


SSL de 2 vías (desde la aplicación alojada en GAE hasta el mundo exterior) no es compatible por lo que sé. Probé una aplicación de muestra hace unos meses y me frustré al encontrar que GAE ni siquiera es compatible con esta característica básica ... y la documentación tampoco está clara. No podrá presentar el certificado de cliente cuando se ponga en contacto con un servicio web. No hay lugar para almacenarlo, no se puede acceder al almacén de claves.


ListenerSoap soap = new Listener().getListenerSoap();

Espero que mejore

Gracias