使用 MATLAB 的 urlread 命令处理无效的安全证书

发布于 2024-08-09 00:55:05 字数 713 浏览 3 评论 0原文

我正在使用 MATLAB 的 urlread< 访问内部数据库/a> 命令,一切工作正常,直到服务被移动到安全服务器(即使用 HTTPS 地址而不是 HTTP 地址)。现在 urlread 不再成功检索结果。它给出了一个错误:

下载网址错误。您的网络连接可能已关闭或您的代理设置配置不正确。

我认为问题在于该服务使用了无效的数字证书,因为如果我尝试直接在网络浏览器中访问资源,我会收到“不受信任的连接”警告,我可以通过将该网站添加到例外列表来绕过该警告。 urlread 没有明显的方法来处理这个问题。

urlread 正在使用 Java 访问 Web 资源,并且在这一行抛出错误:

inputStream = urlConnection.getInputStream;

其中 urlConnection 是一个 Java 对象:sun.net.www .protocol.https.HttpsURLConnectionImpl

有人建议解决这个问题的方法吗?

I'm accessing an internal database using MATLAB's urlread command, everything was working fine until the service was moved to a secure server (i.e. with an HTTPS address rather than an HTTP address). Now urlread no longer successfully retrieves results. It gives an error:

Error downloading URL. Your network connection may be down or your proxy settings improperly configured.

I believe the problem is that the service is using an invalid digital certificate since if I try to access the resource directly in a web browser I get "untrusted connection" warning which I am able to pass through by adding the site to an Exception list. urlread doesn't have an obvious way of handling this problem.

Under the hood urlread is using Java to access web resources, and the error is thrown at this line:

inputStream = urlConnection.getInputStream;

where urlConnection is a Java object: sun.net.www.protocol.https.HttpsURLConnectionImpl.

Anyone suggest a workaround for this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明明#如月 2024-08-16 00:55:05

考虑以下 Java 类。借用此代码: 在 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

首先我们编译 Java 类(我们必须使用与 MATLAB 兼容的 JDK 版本):

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

接下来我们实例化并将其用作 MATLAB:

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

以下是一些要测试的带有不良 SSL 证书的 URL:

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

更新: 我应该提到,从 R2014b 开始,MATLAB 有一个新函数 webread 取代 urlread

Consider the following Java class. Borrowing from this code: Disabling Certificate Validation in an HTTPS Connection

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

First we compile the Java class (we must use a JDK version compatible with MATLAB):

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

Next we instantiate and use it MATLAB as:

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

Here are a few URLs with bad SSL certificates to test:

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

UPDATE: I should mention that starting with R2014b, MATLAB has a new function webread that supersedes urlread.

输什么也不输骨气 2024-08-16 00:55:05

感谢您的解决方案。它有效,但是有时,我收到以下异常“java.io.IOException:在受信任的 CA 列表中找不到颁发者”。我无法摆脱这个错误。

因此,我尝试了一种效果很好的替代解决方案。您可以在Matlab函数中使用以下Java代码:

 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,

thanks for the solution. It worked, however, sometimes, I had received the following exception "java.io.IOException: The issuer can not be found in the trusted CA list." and I was not able to get rid of this error.

Therefore, I tried an alternative solution that works well. You can use the following Java code in Matlab function:

 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

陪我终i 2024-08-16 00:55:05

另请注意,解决此问题的“规范”方法是将证书导入 MATLAB 的密钥库(即,不是 JVM 的密钥库)。

此处记录了这一点:Mathworks 关于使用不受信任的 SSL 证书

Note also that the "canonical" way to solve this issue is to import the certificate into MATLAB's keystore (i.e., not your JVM's keystore).

This is documented here: Mathworks on using untrusted SSL certificates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文