【问题标题】:c# -> Kafka over TLS: "The message received was unexpected or badly formatted"c# -> Kafka over TLS:“收到的消息出乎意料或格式错误”
【发布时间】:2016-08-09 14:29:59
【问题描述】:

我正在尝试从 C# 客户端连接到启用了 TLS 的 Kafka,并在调用 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;
        }
    }
}

【问题讨论】:

  • 如果你有一个协议不匹配,你也可以得到这个,比如如果服务器需要 TLS 1.3 但客户端不支持它。

标签: c# ssl tls1.2


【解决方案1】:

经过一番挖掘,似乎错误消息绝对具有误导性,问题的根本原因是 - 连接过程中缺少“客户端证书的私钥”。

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

【讨论】:

    猜你喜欢
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多