¿Alguien sabe de algún buen tutorial, sitio o libro sobre cómo escribir un comprobador SSL en Java? Estoy tratando de hacer lo que se puede encontrar aquí: http://www.sslshopper.com/ssl-checker.html. No estoy tratando de crear un certificado autofirmado o usar un almacén de claves. Quiero poder ir a cualquier sitio para determinar si existe un Certificado SSL válido, determinar si el nombre de host en el Certificado coincide con el nombre ingresado, y determinar cuándo caducará este Certificado. He buscado este tema en Google, pero "Cómo crear un comprador SSL utilizando Java" no me ha dado nada y mis otras búsquedas solo me trajeron enlaces sobre cómo crear un certificado autofirmado. Cualquier ayuda sería muy apreciada.Escribiendo un Comprobador SSL usando Java
Respuesta
Lo que puede hacer es poner en práctica su propia ficha en la parte superior de por ejemplo Apache's HttpClient
Debe inicializar un contexto SSL y anular el TrustManagers
que comprobar nada que desee.
La biblioteca puede realizar automáticamente la verificación del nombre de host.
E.g. lo siguiente será configurar el manejo de socket SSL para lanzar una excepción si el nombre de host no coincide con los datos del certificado:
SSLSocketFactory sf = new SSLSocketFactory(
SSLContext.getInstance("TLS"),
SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
Para obtener el certificado de servidor en el primer lugar con el fin de hacer la verificación manual, independientemente de si se trata de válido o no, lo más fácil es conectarse a través de un SSLSocket
después de haber desactivado cualquier verificación de certificado.
Crear una SSLContext
que deja nada a través de:
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager passthroughTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { passthroughTrustManager },
null);
(Nota al margen: para personas que buscan una manera de utilizar los certificados de prueba internamente, me gustaría recomendar la construcción de su propia prueba de CA en lugar de deshabilitar comprobaciones, justo en caso de que esas verificaciones se dejen en el código de producción por error, y también porque hace que las pruebas sean más realistas.)
Cree un socket, conéctese e inicie el handshake explícitamente (ya que realmente no va a leer el formulario it):
SSLSocketFactory ssf = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) ssf.createSocket(
"the.host.name", 443);
socket.startHandshake();
Obtiene la cadena de certificados de pares. El primer elemento es el certificado del servidor real.
X509Certificate[] peerCertificates = (X509Certificate[]) socket
.getSession().getPeerCertificates();
Si desea validar contra las anclas de confianza predeterminado (el valor por defecto de confianza certificados CA), construir un X509TrustManager
basado en los valores por defecto (esto es efectivamente lo que el passthroughTrustManager
por encima de personas con discapacidad):
// By default on Oracle JRE, algorithm is PKIX
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// 'null' will initialise the tmf with the default CA certs installed
// with the JRE.
tmf.init((KeyStore) null);
X509TrustManager tm = (X509TrustManager) tmf.getTrustManagers()[0];
Ahora, verifique si el certificado es actualmente válido en el tiempo, si se verifica contra un ancla confiable y si tiene las extensiones correctas de acuerdo con RFC 3280.
try {
// Assuming RSA key here.
tm.checkServerTrusted(peerCertificates, "RSA");
} catch (CertificateException e) {
// Here you may check which subclass of CertificateException to know what the error is.
}
Todo lo anterior hace uso de JSSE API.
Como alternativa, si desea profundizar en los detalles de PKIX, puede utilizar el Java Certification Path API (que es utilizado por JSSE).
(Si solo desea certificados válidos para empezar, simplemente use SSLContext sslContext = SSLContext.getDefault()
al comienzo, cree el socket y realice el intercambio de contactos.)
Para obtener el certificado de servidor directamente, puede utilizar esto:
X509Certificate serverCert = peerCertificates[0];
X509Certificate
tiene una serie de métodos en relación con las fechas y diversas extensiones. Por ejemplo:
Date expirationDate = serverCert.getNotAfter();
La verificación nombre de host debe seguir RFC 6125 (o al menos RFC 2818). En resumen, verifique si el nombre de host al que desea conectarse es una de las entradas de DNS de los Nombres Alternativos del Sujeto (SAN). De lo contrario, vuelva a comprobar si el nombre de host está en el CN RDN de su certificado (para esto, debe dividir el DN del asunto en RDN). También te puede interesar this discussion (on the specific case of using IP addresses).
Todo depende de la cantidad de verificación "manual" que desee realizar. Hay una serie de especificaciones para leer (RFC 5280/RFC 3280 y RFC 6125/RFC 2818 al menos), además de la documentación de API.
Esta pregunta sobre Security.SE también debe ser de interés:
- 1. escribiendo un servidor ftp java
- 2. Java escribiendo en un archivo eliminado
- 3. ¿Hay un comprobador de estilo para C++?
- 4. Escribiendo pestañas en un archivo usando PowerShell
- 5. escribiendo un método público int compareTo() java
- 6. Escribiendo un lector de RSS en Java
- 7. Java cipher.doFinal() escribiendo bytes adicionales
- 8. Comprobador de sintaxis OCL
- 9. escribiendo para sobresalir en java
- 10. Usando libcurl & SSL
- 11. escribiendo un BitSet en un archivo en java
- 12. wcf net.tcp usando SSL
- 13. Java Webstart Truststore SSL
- 14. Escribiendo un java.net.SocketImplFactory
- 15. Cómo conectarse a un sitio web seguro usando SSL en Java con un archivo pkcs12?
- 16. usando spring-ldap con ssl
- 17. Apache ssl redirigir usando mod_rewrite
- 18. escribiendo en el libro existente usando xlwt
- 19. Escribiendo/analizando un archivo de ancho fijo usando Python
- 20. SSL HandShake en Java Client
- 21. escribiendo muchos objetos Java en un único archivo
- 22. Escribiendo datos de entrada de un servlet java a otro
- 23. Escribiendo al comienzo de un archivo de texto Java
- 24. java SSL y cert keystore
- 25. Escribiendo archivos de gran tamaño usando BufferedOutputStream
- 26. Escribiendo modelos MySQL Node.js usando node-mysql
- 27. Java - mkdir() no está escribiendo el directorio
- 28. Escribiendo un destructor LinkedList?
- 29. Autenticación del cliente Tomcat usando SSL
- 30. ¿Es esto un error en el comprobador de contrato estático?
consigo tipos no convertibles cuando se trata de hacer esto: X509Certificate [] = peerCertificates (X509Certificate [ ]) socket.getSession(). getPeerCertificates(); – W3B5T4R
Incluso probé un ejemplo del sitio de Oracles usando lo anterior y sigo obteniendo los "tipos inconvertibles" – W3B5T4R
No importa que vea, estaba usando import javax.security.cert.X509Certificate; en lugar de importar java.security.cert.X509Certificate; – W3B5T4R