c#→Kafka over TLS:“收到的消息出乎意料或格式错误”

本文关键字:出乎意料 消息 格式 错误 Kafka over TLS | 更新日期: 2023-09-27 18:01:25

我正在尝试连接到Kafka,从c#客户端启用TLS,并在呼叫sslStream.AuthenticateAsClient()期间获得异常"收到的消息是意外的或格式化不良的"。不幸的是,到目前为止,互联网上没有任何帖子帮助我解决这个问题。你知道哪里出错了吗?

下面是我用来启动连接的最小c#示例代码

namespace test_tls {
    class Program {
        static string clientCertificateFile = "C:''Temp''<CLIENT_CERTIFICATE_FILE>.crt";
        static X509Certificate2 clientCertificate = new X509Certificate2(clientCertificateFile);
        static void Main(string[] args) {
            var clientCertificateCollection = new X509Certificate2Collection(new X509Certificate2[] { clientCertificate });
            try {
                using( var client = new TcpClient("<IP_ADDRESS>", 9093) )
                using( var sslStream = new SslStream(client.GetStream(), false, CertificateValidator) ) {
                    sslStream.AuthenticateAsClient("<TARGET_HOST_NAME_AS_IN_THE_CERTIFICATE>",
                        clientCertificateCollection, SslProtocols.Tls, false);
                    //send/receive from the sslStream
                }
            }
            catch( Exception e ) {
                Console.Out.WriteLine(e);
                Console.Out.WriteLine("'n'n'nPress ENTER to exit");
                Console.In.ReadLine();
            }
        }
        static bool CertificateValidator(Object sender, 
                X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
            if( sslPolicyErrors == SslPolicyErrors.None ) {
                return true;
            }
            if( sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors ) {
                //we don't have a proper certificate tree
                return true;
            } 
            return false;
        }
    }
}

c#→Kafka over TLS:“收到的消息出乎意料或格式错误”

经过一番挖掘,似乎错误消息绝对是误导,问题的根本原因是- '客户端证书私钥'在连接过程中丢失。

X509Certificate2应该使用以下方式加载

string clientCertificateFile = "C:''path''to''my.certificate.pfx";
X509Certificate2 clientCertificate = new X509Certificate2(clientCertificateFile, "<password>");

或从本地证书存储(应该使用私钥导入)

X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates.Find(X509FindType.FindBySubjectName, "<Certificate 'Issued To' name>", false)[0];

注意:如果你的证书和私钥在不同的文件中,这个命令可以用来合并到PFX文件

openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx