如何使用带有自签名证书/密钥的SslStream / AuthenticateAsServer?

Billpg

我想编写(使用C#和dotnet 4.8)使用TLS进行安全保护的TCP服务。为此,我想将SslStream与TcpListener一起使用,但是我不断收到奇怪的错误。

我的实验程序如下。简单来说:

  • 该程序基于https://stackoverflow.com/a/52535184/3568上的代码创建自签名PFX
  • 它启动一个线程,该线程将在主线程运行客户端时运行服务。
  • 服务线程监听连接。
  • 客户端连接。
  • 该服务发送一行以确认基础TCP连接正常工作。
  • 客户收到线路。
  • 服务器和客户端都将控制权移交给SslStream,服务器使用之前创建的PFX。
    • 这是引发异常的地方。
  • 协商完TLS后,服务器将在TLS通道内发送另一行。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;

namespace TestTlsService
{
    class Program
    {
        static string tempCert;

        static void Main(string[] args)
        {
            /* Create a cert. */
            var cr = new CertificateRequest("cn=this.is.invalid", ECDsa.Create(), HashAlgorithmName.SHA256);
            using (var cert = cr.CreateSelfSigned(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddYears(+1)))
            {
                var exp = cert.Export(X509ContentType.Pfx);
                tempCert = Path.Combine(Path.GetTempPath(), "MySelfSignedCert.pfx");
                File.WriteAllBytes(tempCert, exp);
            }

            /* Launch a service thread. */
            Thread svc = new Thread(ServiceMain);
            svc.Start();
            Thread.Sleep(100);

            /* Connect as a client. */
            using (var tcp = new TcpClient())
            {
                tcp.Connect("localhost", 1984);
                var stream = tcp.GetStream();

                /* Read the line "GoTLS" from the server. */
                var insecureLine = ReadLine(stream);

                /* Hand over control to TLS. */
                using (var tls = new SslStream(stream, false, CheckCert))
                {
                    tls.AuthenticateAsClient("this.is.invalid");

                    /* Read a different line, this time securely. */
                    string line = ReadLine(tls);
                }
            }
        }

        static void ServiceMain()
        {
            /* Open a listener and start listening. */
            var listen = new TcpListener(IPAddress.Loopback, 1984);
            listen.Start();
            using (var tcp = listen.AcceptTcpClient())
            {
                /* Send "GoTLS" to the client insecurely. */
                var stream = tcp.GetStream();
                stream.Write(Encoding.ASCII.GetBytes("GoTLS\r\n"), 0, 7);

                /* Hand over control to TLS, using the self-signed cert from earlier. */
                using (var tls = new SslStream(stream))
                {
                    var cert = new X509Certificate2(tempCert);
                    tls.AuthenticateAsServer(cert);

                    /* Send a new message inside the secure channel. */
                    tls.Write(Encoding.ASCII.GetBytes("Hello\r\n"), 0, 7);
                }
            }
        }

        /* Simple function that just reads a line. */
        static string ReadLine(Stream stream)
        {
            byte[] line = new byte[100];
            int bytesIn = stream.Read(line, 0, 100);
            string lineAscii = Encoding.ASCII.GetString(line, 0, bytesIn);
            return lineAscii;
        }

        /* Accept all certificates. DO NOT COPY THIS INTO YOUR OWN CODE! */
        private static bool CheckCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            /* The full version will check the cert, but for now we'll just... */
            return true;
        }
    }
}

该程序在AuthenticateAsServer行中引发AuthenticationException,并显示消息“对SSPI的调用失败,请参阅内部异常”。而内部异常具有“客户端和服务器无法通信,因为它们不具有通用算法”。我发现SslStream库本身找不到通用协议的可能性很小。

我怀疑问题的根源在于我使用的是自签名证书,因为我可以找到的所有AuthenticateAsServer示例都使用预生成的证书文件,可惜我没有。

如何在服务器端使用SslStream与自签名证书协商TLS?


要抢先预期的问题...

我知道客户端可以正常工作,因为我已用邮件服务器替换了“ localhost”(并跳过了“只读”行),并且客户端线程可以正常工作,以读取TLS发出后远程邮件服务器发送的安全欢迎行经过谈判。

设置ServicePointManager.SecurityProtocolTls12无济于事。

如果删除pre-SslStream“ GoTLS”交换,则会收到相同的错误。

我搜索了错误消息。我能找到的所有答案都建议将SecurityProtocol设置为Tls12,我已经尝试过了。

我尝试使用其他格式的证书而不是PFX,但是在抱怨缺少私钥时遇到了其他错误。

EVK

我不知道为什么,但是不喜欢您签发的ECDSA证书。如果改为使用标准RSA:

var cr = new CertificateRequest(new X500DistinguishedName("cn=this.is.invalid"), RSA.Create(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

并保留其他所有内容-然后它将按预期工作。从理论上讲,TLS支持ECC(椭圆曲线)密钥,但是我对此并不熟练,并且不确定为什么SslStream.AuthenticateAsServer不喜欢该证书。希望您不需要专门的ECC,那么使用RSA的上述解决方法就可以了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有可选ClientCertificate的SslStream AuthenticateAsServer

来自分类Dev

具有可选ClientCertificate的SslStream AuthenticateAsServer

来自分类Dev

禁用AuthenticateAsServer的证书验证似乎无效

来自分类Dev

SslStream AuthenticateAsServer失败,并显示“服务器证书私钥不可用”。单声道异常

来自分类Dev

.NET SslStream AuthenticateAsServer可以尊重客户端发送的服务器名称指示器吗?

来自分类Dev

使用带有cURL的自签名证书?

来自分类Dev

自签名密钥证书

来自分类Dev

如何使用feh打开带有自签名证书的Web图像

来自分类Dev

如何在 osx 上使用带有自签名证书的 docker 容器?

来自分类Dev

带有自签名证书的TLS

来自分类Dev

带有自签名证书的AFNetwork

来自分类Dev

带有自签名证书的后端

来自分类Dev

停留在 mitm https 代理中的 AuthenticateAsServer 方法上

来自分类Dev

在带有自签名证书的Python中使用请求时,证书验证失败

来自分类Dev

Windows:如何创建自签名根证书以及使用自签名根证书签名的自签名证书

来自分类Dev

如何在Android混合应用程序中打开HTTPS页面(带有自签名证书)

来自分类Dev

使用自签名证书通过HTTPS进行带有CORS请求的Phonegap应用

来自分类Dev

使用带有自签名证书和Pidgin的Tigase XMPP时,“未授权”

来自分类Dev

带有自签名证书的Swift SSL错误

来自分类Dev

SSLHandshake失败(-9808),带有自签名根证书

来自分类Dev

如何部署自签名证书?

来自分类Dev

create-react-app:如何使用带有已签名证书的https?

来自分类Dev

在Java中使用自签名证书时SSL如何工作

来自分类Dev

如何使用WinHTTP通过自签名证书执行SSL

来自分类Dev

如何通过使用自签名证书来限制访问?

来自分类Dev

Swift:如何使用自签名证书请求URL?

来自分类Dev

如何使用自签名OpenSSL证书在HTTPS上测试PWA?

来自分类Dev

如何使用WinHTTP通过自签名证书执行SSL

来自分类Dev

如何使用我作为 JSON 获得的自签名证书?

Related 相关文章

  1. 1

    具有可选ClientCertificate的SslStream AuthenticateAsServer

  2. 2

    具有可选ClientCertificate的SslStream AuthenticateAsServer

  3. 3

    禁用AuthenticateAsServer的证书验证似乎无效

  4. 4

    SslStream AuthenticateAsServer失败,并显示“服务器证书私钥不可用”。单声道异常

  5. 5

    .NET SslStream AuthenticateAsServer可以尊重客户端发送的服务器名称指示器吗?

  6. 6

    使用带有cURL的自签名证书?

  7. 7

    自签名密钥证书

  8. 8

    如何使用feh打开带有自签名证书的Web图像

  9. 9

    如何在 osx 上使用带有自签名证书的 docker 容器?

  10. 10

    带有自签名证书的TLS

  11. 11

    带有自签名证书的AFNetwork

  12. 12

    带有自签名证书的后端

  13. 13

    停留在 mitm https 代理中的 AuthenticateAsServer 方法上

  14. 14

    在带有自签名证书的Python中使用请求时,证书验证失败

  15. 15

    Windows:如何创建自签名根证书以及使用自签名根证书签名的自签名证书

  16. 16

    如何在Android混合应用程序中打开HTTPS页面(带有自签名证书)

  17. 17

    使用自签名证书通过HTTPS进行带有CORS请求的Phonegap应用

  18. 18

    使用带有自签名证书和Pidgin的Tigase XMPP时,“未授权”

  19. 19

    带有自签名证书的Swift SSL错误

  20. 20

    SSLHandshake失败(-9808),带有自签名根证书

  21. 21

    如何部署自签名证书?

  22. 22

    create-react-app:如何使用带有已签名证书的https?

  23. 23

    在Java中使用自签名证书时SSL如何工作

  24. 24

    如何使用WinHTTP通过自签名证书执行SSL

  25. 25

    如何通过使用自签名证书来限制访问?

  26. 26

    Swift:如何使用自签名证书请求URL?

  27. 27

    如何使用自签名OpenSSL证书在HTTPS上测试PWA?

  28. 28

    如何使用WinHTTP通过自签名证书执行SSL

  29. 29

    如何使用我作为 JSON 获得的自签名证书?

热门标签

归档