Java HTTPS cliente no reconocimiento de SSL mientras rizo tiene éxito

Zik:

Disculpas por adelantado, todavía estoy bastante nuevo en la codificación de SSL. He estado buscando respuestas para los últimos días, y mientras yo he encontrado una gran cantidad de sugerencias nada ha funcionado hasta ahora.

Lo que tengo es un servidor implementado en la parte superior de Dropwizard que tiene que aceptar una conexión HTTPS entrante y utilizan el certificado adjunto para identificar de forma única el cliente. Actualmente estoy usando todos los certificados firmados mientras estoy en el desarrollo. La pareja certificado de servidor se ha creado usando una cadena - par de raíz -> par intermedio -> par de servidores. P12 del servidor se ha creado usando una concatenación de los certificados intermedios y de servidor más la clave privada del servidor. A continuación, se añadió a una JKS vacío y se convirtió en almacén de claves del servidor.

Por otra parte he creado dos certificados de cliente, una con el mismo par intermedia como la base, y otro como un par certificado independiente puro. La parte clave pública x509 de estos dos pares de certificados se añadió a un archivo JKS y se convirtió en TrustStore del servidor. La configuración Dropwizard sigue:

type: "https"
port: "9843"
keyStorePath: "keystore.jks"
keyStorePassword: "changeme"
keyStoreType: "JKS"
trustStorePath: "truststore.jks"
trustStorePassword: "changeme"
trustStoreType: "JKS"
allowRenegotiation: false
validateCerts: false
validatePeers: false
needClientAuth: true
wantClientAuth: true

Puedo conectar con el servidor utilizando curly cualquiera de los pares de certificados de cliente:

curl -v --cert client.pem --key client.key -k https://localhost:9843/v1/ld 

Con SSL depuración activada, el servidor registra lo siguiente:

*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:
<CN=*.me.com, O=Me, ST=Massachusetts, C=US>
<O=Internet Widgits Pty Ltd, ST=Massachusetts, C=US>
*** ServerHelloDone
dw-51, WRITE: TLSv1.2 Handshake, length = 3536
dw-44, READ: TLSv1.2 Handshake, length = 1047
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: O=Internet Widgits Pty Ltd, L=North Reading, ST=Massachusetts, C=US
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 2048 bits
  modulus: 23250299629324311533731283912176366463399376328149948822580485256237233115567136794461732268017120297060017586981907979910958857247642884566364833267711927344361604478514119965230314679194017013023991389216461419030751049820266939279047536006291610734616600760688907006770883510297954698233112783686968024400749969025850008781641616624298935923926427096257861170476293580684942956111432790304698635393966967864288730561678135798437678912431564767611000006312358137647455886578135011989168265295083928014176435879778838966450081419161406209555593636745048857672445188811541416453143809594265089422302064600885289819601
  public exponent: 65537
  Validity: [From: Wed Dec 05 13:52:49 EST 2018,
               To: Thu Dec 05 13:52:49 EST 2019]
  Issuer: O=Internet Widgits Pty Ltd, ST=Massachusetts, C=US
  SerialNumber: [    8174655c c8387da4]

Certificate Extensions: 3
...

Hasta aquí todo bien. Siguiente Trato de conectar con el servidor usando un cliente Java utilizando el mismo par de certificados, combinados en un solo archivo P12. código Java sigue:

char[] password = "changeme".toCharArray();
KeyStore keystore = KeyStore.getInstance("PKCS12");
try (FileInputStream fileInputStream = new FileInputStream("client.p12")) {
    keystore.load(fileInputStream, password);
}

SSLContext sslContext = 
        SSLContexts.custom()
                   .loadKeyMaterial(keystore, password)
                   .loadTrustMaterial(null, (chain, authType) -> true)
                   .build();

return HttpClients.custom()
                  .setSSLContext(sslContext)
                  .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                  .build();

Pero cuando este cliente intenta conectarse al servidor registra el siguiente:

*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:
<CN=*.me.com, O=Me, ST=Massachusetts, C=US>
<O=Internet Widgits Pty Ltd, ST=Massachusetts, C=US>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***

También he intentado usar un SSLConnectionSocketFactoryinicializado con el SSLContext, y un Registry<ConnectionSocketFactory>registro de la socketFactory "https". Nada ha funcionado. Estoy totalmente en una pérdida de por qué curlacepta las autoridades cert y envía el certificado de cliente pero el java HttpClient no lo hace.

EDITAR:

He intentado añadir el certificado público del servidor a la petición del cliente, que no hizo una diferencia - Todavía estoy viendo el mismo comportamiento. El código se actualiza como sigue:

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
try (FileInputStream fileInputStream = new FileInputStream("server.cert.pem")) {
    try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(IOUtils.toByteArray(fileInputStream))) {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
        Certificate certificate = certificateFactory.generateCertificate(byteArrayInputStream);
        trustStore.setCertificateEntry("server", certificate);
    }
}

SSLContext sslContext =
        SSLContexts.custom()
                   .loadKeyMaterial(keystore, password)
                   .loadTrustMaterial(trustStore, (chain, authType) -> true)
                   .build();
Zik:

Así que acabé volver a trabajar por completo cómo se generaban mis certificados y que era capaz de hacer las cosas de trabajo, con una advertencia: que dependía de cómo se generaron los certificados.

Funciona con cliente Java, rizo, y el cartero:

openssl genrsa -aes256 -out private/${SVRNAME}.key.pem 2048
openssl req -config ${CONFIGDIR}/openssl.cnf \
      -new -x509 -days 7300 -sha256 -extensions v3_ca \
      -key private/${SVRNAME}.key.pem \
      -out certs/${SVRNAME}.cert.pem

Funciona con el enrollamiento y el cliente cartero, pero no de Java:

openssl req -newkey rsa:2048 -nodes \
      -keyout private/${CLINAME}.key.pem \
      -x509 -days 365 -out certs/${CLINAME}.cert.pem

No sé por qué el certificado "rápida" causado tantos problemas, pero al menos está trabajando ahora. Gracias a Patrick y Dave por la ayuda!

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=235371&siteId=1
Recomendado
Clasificación