如何使Restlet客户端忽略SSL证书问题

nwa*_*ham 6 java ssl https restlet

我目前正在测试环境中工作,其中服务器具有默认的自签名SSL证书.我正在使用Restlet 2.1-RC2并实例化客户端资源,如下所示:

Client client = new Client(new Context(), Protocol.HTTP);
cr = new ClientResource(String.format(itql_endpoint,riQuery));
cr.setNext(client);
Run Code Online (Sandbox Code Playgroud)

并为我的每个电话重复使用客户端.如何设置客户端以便忽略有问题的证书.

Bru*_*uno 9

正确的方法是将此自签名证书导入客户端的信任存储区,keytool例如:

keytool -import -file server-cert.pem -alias myserver -keystore mytruststore.jks
Run Code Online (Sandbox Code Playgroud)

您可以直接在JRE的信任存储(lib/security/cacerts)中执行此操作(可能缺少一些灵活性),也可以在您自己的此文件副本中执行此操作,然后将其设置为信任存储(默认密码为changeitchangeme在OSX上).您可以使用常用的javax.net.ssl.trustStore*系统属性(例如-Djavax.net.ssl.trustStore=mytruststore系统属性(和-Djavax.net.ssl.trustStorePassword))为您的应用程序全局配置此信任库,或者您可以使用服务器上下文参数为Restlet中的特定连接器配置它,例如:

Series<Parameter> parameters = client.getContext().getParameters();
parameters.add("truststorePath", "/path/to/your/truststore.jks");
// parameters.add("truststorePassword", "password");
// parameters.add("trustPassword", "password");
// parameters.add("truststoreType", "JKS");
Run Code Online (Sandbox Code Playgroud)

错误的方法是使用一个TrustManager将禁用任何验证并通过SslContextFactory(在SSL扩展中)传递它.沿着这些方向的东西.

TrustManager tm = new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain,
                    String authType)
                    throws CertificateException {
    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }

    public void checkServerTrusted(X509Certificate[] chain,
                    String authType)
                    throws CertificateException {
        // This will never throw an exception.
        // This doesn't check anything at all: it's insecure.
    }
};

final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] {tm}, null);
Context context = client.getContext();
context.getAttributes().put("sslContextFactory", new SslContextFactory() {
    public void init(Series<Parameter> parameters) { }
    public SSLContext createSslContext() { return sslContext; }
});
Run Code Online (Sandbox Code Playgroud)

虽然第一种方法似乎比第二种方法更乏味(因为您需要先获取服务器证书并复制文件),但第二种方法只是通过不验证服务器证书的任何内容而使错误消息消失,从而使它容易受到MITM主动攻击.这将适用于SSLContext配置此连接的任何连接.(这种"错误的方式没有错,因为它使用了自定义SSLContext,因为这个特殊的配置是错误的SSLContext.)

  • 我必须承认,我不记得如何调整主机名验证.最好的方法是使用具有正确名称的自签名证书.通常,只在主题DN中设置CN应该这样做,但您也可以设置主题Alt名称(如果使用IP地址,则需要它),请参阅http://stackoverflow.com/a/8444863/372643 (2认同)