Manejo de un certificado de seguridad inválido usando el comando urlread de MATLAB
-
08-07-2019 - |
Pregunta
Estoy accediendo a una base de datos interna utilizando urlread de MATLAB
, todo funcionaba bien hasta que el servicio se movió a un servidor seguro (es decir, con una dirección HTTPS en lugar de una dirección HTTP). Ahora code>
urlread
ya no recupera resultados con éxito. Da un error:
Error al descargar la URL. Su conexión de red puede estar inactiva o su configuración de proxy está configurada incorrectamente.
Creo que el problema es que el servicio está utilizando un certificado digital no válido, ya que si trato de acceder al recurso directamente en un navegador web, obtengo una conexión no confiable. advertencia que puedo pasar agregando el sitio a una lista de excepciones. urlread
no tiene una forma obvia de manejar este problema.
Bajo el capó urlread
está utilizando Java para acceder a los recursos web, y el error aparece en esta línea:
inputStream = urlConnection.getInputStream;
donde urlConnection
es un objeto Java: sun.net.www.protocol.https.HttpsURLConnectionImpl
.
¿Alguien sugiere una solución para este problema?
Solución
Considere la siguiente clase de Java. Usé esta página como referencia:
Deshabilitar la validación de certificados en una conexión HTTPS
C: \ MATLAB \ MyJavaClasses \ com \ stackoverflow \ Downloader.java
package com.stackoverflow;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.HostnameVerifier;
public class Downloader {
public static String getData(String address) throws Exception {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Create a host name verifier that always passes
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
// open connection
URL page = new URL(address);
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// read text
String line;
StringBuffer text = new StringBuffer();
while ( (line = buff.readLine()) != null ) {
//System.out.println(line);
text.append(line + "\n");
}
buff.close();
return text.toString();
}
public static void main(String[] argv) throws Exception {
String str = getData("https://expired.badssl.com/");
System.out.println(str);
}
}
MATLAB
Primero compilamos la clase Java (debemos usar una versión JDK compatible con MATLAB):
>> version -java
>> system('javac C:\MATLAB\MyJavaClasses\com\stackoverflow\Downloader.java');
A continuación, instanciamos y usamos MATLAB como:
javaaddpath('C:\MATLAB\MyJavaClasses')
dl = com.stackoverflow.Downloader;
str = char(dl.getData('https://expired.badssl.com/'));
web(['text://' str], '-new')
Aquí hay algunas URL con certificados SSL incorrectos para probar:
urls = {
'https://expired.badssl.com/' % expired
'https://wrong.host.badssl.com/' % wrong host
'https://self-signed.badssl.com/' % self-signed
'https://revoked.grc.com/' % revoked
};
ACTUALIZACIÓN: debo mencionar que a partir de R2014b, MATLAB tiene una nueva función webread
que reemplaza a urlread
.
Otros consejos
gracias por la solución. Funcionó, sin embargo, a veces, recibí la siguiente excepción "java.io.IOException: El emisor no se puede encontrar en la lista de CA de confianza". y no pude deshacerme de este error.
Por lo tanto, probé una solución alternativa que funciona bien. Puede usar el siguiente código Java en la función Matlab:
function str = ReadUrl(url)
is = java.net.URL([], url, sun.net.www.protocol.https.Handler).openConnection().getInputStream();
br = java.io.BufferedReader(java.io.InputStreamReader(is));
str = char(br.readLine());
end
Mejor, Jan
Tenga en cuenta también que el "canónico" La forma de resolver este problema es importar el certificado al almacén de claves de MATLAB (es decir, no el almacén de claves de su JVM).
Esto se documenta aquí: Mathworks sobre el uso de certificados SSL no confiables .