是否可以在Apache Kafka Java客户端中禁用SSL证书验证?

是否可以在Apache Kafka Java客户端中禁用SSL证书验证?,java,ssl,apache-kafka,Java,Ssl,Apache Kafka,如果我有一个自签名证书,作为一个好公民,我会将它导入我的密钥库,并使用“ssl.truststore.location”和“ssl.truststore.type”配置Kafka客户端以使用它 如果证书主题的公共名称可能与提供它的主机地址不同,我可以使用“ssl.endpoint.identification.algorithm”关闭端点验证 如果我想完全跳过SSL验证,而不仅仅是主机名验证,这样我就不再需要复制证书了,该怎么办?类似于curl中的“-k”或“-unsecure”设置。我可以用K

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

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


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

有一种方法可以实现它,但是它并不那么简单

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

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) {

    }
}
或者,如果不想使用常数:

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

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

我发现这在java中非常有用。@ShivamPuri是的,使用noop TrustManager在java中完成这项工作,我在这里寻找类似的解决方案。但是Kafka客户端会自动初始化,就我而言,我只能用它公开的设置来配置它,所以我找不到办法。如果你都跳过了认证和主机名验证,感觉就像你想使用纯文本而不是SSL@MickaelMaison,没有身份验证的SSL仍然有用。即使您不在连接的任何一端进行身份验证,加密的网络流量也是一个好处。最好添加导入部分已添加导入部分。
props.put("ssl.engine.factory.class", MySslEngineFactory.class);