¿Cómo puedo pasar el certificado de cliente en cliente HTTP?

Quiero usar mutua autenticación SSL entre el servicio de a y B. actualmente estoy implementando pasando el certificado de cliente de servicio de Una en Java. Estoy usando Apache DefaultHttpClient para ejecutar mis peticiones. Yo era capaz de recuperar el certificado de cliente para mi servicio Un de un interno administrador de credenciales y la tengo como una matriz de bytes.

DefaultHttpClient client = new DefaultHttpClient();
byte [] certificate = localCertManager.retrieveCert();

Tengo muy poca experiencia en esta área y apreciaría su ayuda!

Pensé que tal vez debería ser de alguna manera pasa a través de argumentos en el cliente HTTP o tal vez en las cabeceras.

¿Cómo puedo pasar el certificado de cliente en cliente HTTP?

OriginalEl autor agerrr | 2013-08-30

2 Kommentare

  1. 10

    Usted necesita decirle a un SSLSocketFactory (org.apache.http, no javax) acerca de su almacén de claves, y configurar su DefaultHTTPClient a utilizar para las conexiones https.

    Un ejemplo está aquí: http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java

    Fresco, esto fue realmente útil!
    Este es vagamente correcta para empezar, pero los enlaces de ejemplo, confunde las cosas, por no utilizar certificados de cliente. Lo que realmente establece alternativa CA cert para confiar en que el servidor está conectado a la vez, pero puede aparecer a alguien que no está íntimamente familiarizado con SSLContexts para ser un ejemplo correcto. He seguido este y tomó mucho tiempo para desentrañar el que loadTrustMaterial no funciona.

    OriginalEl autor covener

  2. 5

    El certificado de cliente es enviado durante la negociación TLS cuando se establece una conexión y no puede ser enviado a través de HTTP, dentro de esa conexión.

    La comunicación es capas de como esta:

    • HTTP (de la capa de aplicación del protocolo) dentro de
    • TLS (presentación de protocolo de capa) dentro de
    • (TCP en la capa de transporte el protocolo) dentro de
    • IP (protocolo de capa de red)

    Usted necesita para enviar el certificado de cliente durante la negociación TLS antes de nada HTTP (métodos, los encabezados, las direcciones Url, a solicitud de los órganos) está disponible para ser influenciado. El servidor no aceptará un certificado de cliente enviados más tarde.

    Estoy recomendando cambiar de DefaultHttpClient (obsoleto) a CloseableHttpClient que funciona de una manera más limpia con intentar-con-recursos.

    Apache HttpClient 4.5 hace TLS Mutua razonablemente conveniente. Esta respuesta ha sido probado con Apache HttpClient 4.5.3.

    El punto de partida esencial es el uso de loadKeyMaterial para cargar el cliente de certicado y es clave (el cliente par de claves) en el SSLContext:

    SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(
                    MutualHttpsMain.class.getResource(TEST_CLIENT_KEYSTORE_RESOURCE),
                    password, password,
                    (aliases, socket) -> aliases.keySet().iterator().next()
            ).build();
    

    Y, finalmente, la construcción de un cliente HTTP con zócalo de fábrica:

    CloseableHttpClient httpclient = HttpClients
            .custom().setSSLContext(sslContext).build();
    

    Con ese cliente, todas las solicitudes se pueden realizar con Mutuo TLS autenticación implícita:

    CloseableHttpResponse closeableHttpResponse = httpclient.execute(
            new HttpGet(URI.create("https://mutual-tls.example.com/")));
    

    He aquí un completo ejecutables ejemplo de mutuo TLS con Apache HttpClient:

    import org.apache.http.HttpEntity;
    import org.apache.http.StatusLine;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.ssl.SSLContexts;
    
    import javax.net.ssl.SSLContext;
    import java.io.Console;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URI;
    import java.nio.ByteBuffer;
    import java.nio.channels.Channels;
    import java.nio.channels.ReadableByteChannel;
    import java.nio.channels.WritableByteChannel;
    import java.security.GeneralSecurityException;
    
    public class MutualHttpsMain {
        private static final String TEST_URL = "https://mutual-tls.example.com/";
        private static final String TEST_CLIENT_KEYSTORE_RESOURCE = "/mutual-tls-keystore.p12";
    
        public static void main(String[] args) throws GeneralSecurityException, IOException {
            Console console = System.console();
            char[] password = console.readPassword("Keystore password: ");
            SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(
                    MutualHttpsMain.class.getResource(TEST_CLIENT_KEYSTORE_RESOURCE),
                    password, password,
                    (aliases, socket) -> aliases.keySet().iterator().next()
            ).build();
            try (CloseableHttpClient httpclient = HttpClients
                    .custom().setSSLContext(sslContext).build();
                 CloseableHttpResponse closeableHttpResponse = httpclient.execute(
                        new HttpGet(URI.create(TEST_URL)))) {
                console.writer().println(closeableHttpResponse.getStatusLine());
                HttpEntity entity = closeableHttpResponse.getEntity();
                try (InputStream content = entity.getContent();
                     ReadableByteChannel src = Channels.newChannel(content);
                     WritableByteChannel dest = Channels.newChannel(System.out)) {
                    ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
                    while (src.read(buffer) != -1) {
                        buffer.flip();
                        dest.write(buffer);
                        buffer.compact();
                    }
                    buffer.flip();
                    while (buffer.hasRemaining())
                        dest.write(buffer);
                }
            }
        }
    }
    

    Es generalmente mejor para el uso de Gradle o Maven para ejecutar algo como esto, pero en el interés de mantener este Yak rasurada al mínimo posible estoy de referencia JDK instrucciones para la construcción y ejecución de este.

    Descarga de los Frascos de las siguientes páginas:

    Guardar el ejemplo completo sobre como MutualHttpsMain.java.

    Copia su archivo PKCS#12 para mutuo-tls-almacén de claves.p12 en el mismo directorio.

    Compilar de la siguiente manera (en macOS/Linux/*nix-le gusta):

    javac MutualHttpsMain.java -cp httpclient-4.5.3.jar:httpcore-4.4.8.jar
    

    O en Windows:

    javac MutualHttpsMain.java -cp httpclient-4.5.3.jar;httpcore-4.4.8.jar
    

    Ejecutar de la siguiente manera (en macOS/Linux/*nix-le gusta):

    java -cp httpclient-4.5.3.jar:commons-codec-1.10.jar:commons-logging-1.2.jar:httpcore-4.4.8.jar:. MutualHttpsMain
    

    Ejecutar de la siguiente manera (en Windows):

    java -cp httpclient-4.5.3.jar;commons-codec-1.10.jar;commons-logging-1.2.jar;httpcore-4.4.8.jar;. MutualHttpsMain
    
    tiene una concisa ejemplo TLS mutua java cliente HTTP ejemplo aquí stackoverflow.com/a/32513368/154527

    OriginalEl autor Alain O’Dea

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea