Domanda

Sto accedendo a un database interno utilizzando urlread di MATLAB , tutto funzionava bene fino a quando il servizio non veniva spostato su un server sicuro (ovvero con un indirizzo HTTPS anziché un indirizzo HTTP). Ora urlread non recupera più correttamente i risultati. Dà un errore:

  

Errore durante il download dell'URL. La connessione di rete potrebbe essere inattiva o le impostazioni del proxy non configurate correttamente.

Credo che il problema sia che il servizio utilizza un certificato digitale non valido poiché se provo ad accedere alla risorsa direttamente in un browser web ottengo "connessione non attendibile" avviso a cui sono in grado di passare aggiungendo il sito a un elenco di eccezioni. urlread non ha un modo ovvio di gestire questo problema.

Under the hood urlread utilizza Java per accedere alle risorse Web e l'errore viene generato in questa riga:

inputStream = urlConnection.getInputStream;

dove urlConnection è un oggetto Java: sun.net.www.protocol.https.HttpsURLConnectionImpl .

Qualcuno suggerisce una soluzione per questo problema?

È stato utile?

Soluzione

Considera la seguente classe Java. Ho usato questa pagina come riferimento:

  

Disabilitazione della convalida del certificato in una connessione 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

Per prima cosa compiliamo la classe Java (dobbiamo usare una versione JDK compatibile con MATLAB):

>> version -java
>> system('javac C:\MATLAB\MyJavaClasses\com\stackoverflow\Downloader.java');

Quindi istanziamo e usiamo MATLAB come:

javaaddpath('C:\MATLAB\MyJavaClasses')
dl = com.stackoverflow.Downloader;
str = char(dl.getData('https://expired.badssl.com/'));
web(['text://' str], '-new')

Ecco alcuni URL con certificati SSL non validi da testare:

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
};

AGGIORNAMENTO: Dovrei menzionare che a partire da R2014b, MATLAB ha una nuova funzione webread che sostituisce urlread .

Altri suggerimenti

grazie per la soluzione. Funzionava, tuttavia, a volte, avevo ricevuto la seguente eccezione "java.io.IOException: l'emittente non è stato trovato nell'elenco CA attendibile." e non sono riuscito a liberarmi di questo errore.

Pertanto, ho provato una soluzione alternativa che funziona bene. È possibile utilizzare il seguente codice Java nella funzione 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

Best, Jan

Nota anche che il "canonico" il modo per risolvere questo problema è importare il certificato nel keystore di MATLAB (ovvero non nel keystore della tua JVM).

Questo è documentato qui: Mathworks sull'uso di certificati SSL non attendibili .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top