【问题标题】:Is it possible to disable SSL certificate verification in Apache Kafka Java client?是否可以在 Apache Kafka Java 客户端中禁用 SSL 证书验证?
【发布时间】:2019-12-13 08:18:56
【问题描述】:

如果我有自签名证书,作为一个好公民,我会将其导入我的密钥库并使用“ssl.truststore.location”和“ssl.truststore.type”配置Kafka客户端以便使用它。

如果期望证书主题中的公用名可能与提供它的主机地址不同,我可以使用“ssl.endpoint.identification.algorithm”关闭端点验证。

如果我想完全跳过 SSL 验证,而不仅仅是主机名,那么我不再需要复制证书怎么办?类似于 curl 中的“-k”或“--insecure”设置。我可以使用 Kafka 的默认 Java 客户端吗?

【问题讨论】:

  • 我发现 stackoverflow.com/a/54517407/11226302 在 java 中同样非常有用。
  • @ShivamPuri 是的,使用 noop TrustManager 可以在 Java 中完成这项工作,我在这里寻找类似的解决方案。但是 Kafka 客户端会自行初始化,就我而言,我只能使用它公开的设置来配置它,所以我没有办法这样做。
  • 如果您同时跳过认证和主机名验证,感觉就像您想使用 PLAINTEXT 而不是 SSL
  • @MickaelMaison,没有身份验证的 SSL 仍然有用。即使您没有在连接的任一端进行身份验证,加密的网络流量也是一个好处。

标签: java ssl apache-kafka


【解决方案1】:

有一种方法可以完成它,但它并不那么简单。

这个想法是实现将忽略证书验证的接口 org.apache.kafka.common.security.auth.SslEngineFactory。当您将其用作客户端时,只需以类似于以下方式实现 createClientSslEngine 方法就足够了:

import org.apache.kafka.common.security.auth.SslEngineFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Set;

public static class MySslEngineFactory implements SslEngineFactory {
    @Override
    public SSLEngine createClientSslEngine(String peerHost, int peerPort, String endpointIdentification) {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() { return null; }
                public void checkClientTrusted(X509Certificate[] certs, String authType) { }
                public void checkServerTrusted(X509Certificate[] certs, String authType) { }
            }};
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLEngine sslEngine = sc.createSSLEngine(peerHost, peerPort);
            sslEngine.setUseClientMode(true);
            return sslEngine;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public SSLEngine createServerSslEngine(String peerHost, int peerPort) {
        return null;
    }

    @Override
    public boolean shouldBeRebuilt(Map<String, Object> nextConfigs) {
        return false;
    }

    @Override
    public Set<String> reconfigurableConfigs() {
        return null;
    }

    @Override
    public KeyStore keystore() {
        return null;
    }

    @Override
    public KeyStore truststore() {
        return null;
    }

    @Override
    public void close() throws IOException {

    }

    @Override
    public void configure(Map<String, ?> configs) {

    }
}

完成此类后,您只需在 kafka(生产者或消费者)属性中将其配置为 SSL_ENGINE_FACTORY_CLASS:

props.put(SslConfigs.SSL_ENGINE_FACTORY_CLASS, MySslEngineFactory.class);

或者如果您不想使用该常量:

props.put("ssl.engine.factory.class", MySslEngineFactory.class);

确保不要在生产中使用此设置!

【讨论】:

  • 添加导入部分会很好
  • 已添加导入部分。
猜你喜欢
  • 2015-08-07
  • 2012-02-15
  • 2019-06-28
  • 1970-01-01
  • 2013-06-20
  • 2017-05-18
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多