Pregunta

Estoy accediendo a una base de datos interna utilizando urlread de MATLAB code> , 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 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?

¿Fue útil?

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 .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top