System.Net.WebRequest和TLS 1.2创建了一个'握手失败'与haproxy

时间:2017-12-07 15:06:06

标签: .net c#-4.0 httpwebrequest haproxy tls1.2

我无法将System.Net.WebRequest用于使用TLS 1.2的请求。 如果我这样做,我会收到异常The request was aborted: Could not create SSL/TLS secure channel.和协议错误Handshake Failure

通过TLS 1.2连接和身份验证可与Internet Explorer和Chrome配合使用。 OpenSSL可以通过TLS 1.2连接到这个端点。

设置

  1. 使用ClientCertificates进行身份验证
  2. 使用非默认端口
  3. 使用TLS 1.2
  4. 端点是haproxy,但这是一个黑盒子
  5. .NET 4.7和C#
  6. 代码snipplet

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    var req = WebRequest.Create($"https://{host}:{port}");
    ((HttpWebRequest)req).ClientCertificates = new X509Certificate2Collection(GetCertificate());
    var requestStream = req.GetRequestStream();
    

    方法GetCertificate()返回带有私钥的证书,该私钥嵌入在此软件中。

    的Wireshark

    按照发生的顺序从wireshark输出文本。

    客户端您好

    Secure Sockets Layer
        TLSv1.2 Record Layer: Handshake Protocol: Client Hello
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 207
            Handshake Protocol: Client Hello
                Handshake Type: Client Hello (1)
                Length: 203
                Version: TLS 1.2 (0x0303)
                Random: 5a292ab72d2173fc286aebe2c4cc991ee619e1cc81b5bb39...
                Session ID Length: 0
                Cipher Suites Length: 60
                Cipher Suites (30 suites)
                Compression Methods Length: 1
                Compression Methods (1 method)
                Extensions Length: 102
                Extension: server_name (len=43)
                    Type: server_name (0)
                    Length: 43
                    Server Name Indication extension
                        Server Name list length: 41
                        Server Name Type: host_name (0)
                        Server Name length: 38
                        Server Name: [REMOVED]
                Extension: supported_groups (len=8)
                    Type: supported_groups (10)
                    Length: 8
                    Supported Groups List Length: 6
                    Supported Groups (3 groups)
                Extension: ec_point_formats (len=2)
                    Type: ec_point_formats (11)
                    Length: 2
                    EC point formats Length: 1
                    Elliptic curves point formats (1)
                Extension: signature_algorithms (len=20)
                    Type: signature_algorithms (13)
                    Length: 20
                    Signature Hash Algorithms Length: 18
                    Signature Hash Algorithms (9 algorithms)
                Extension: SessionTicket TLS (len=0)
                    Type: SessionTicket TLS (35)
                    Length: 0
                    Data (0 bytes)
                Extension: extended_master_secret (len=0)
                    Type: extended_master_secret (23)
                    Length: 0
                Extension: renegotiation_info (len=1)
                    Type: renegotiation_info (65281)
                    Length: 1
                    Renegotiation Info extension
                        Renegotiation info extension length: 0
    

    Server Name: [REMOVED]包含正确的服务器名称。

    服务器您好

    Secure Sockets Layer
        TLSv1.2 Record Layer: Handshake Protocol: Server Hello
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 65
            Handshake Protocol: Server Hello
                Handshake Type: Server Hello (2)
                Length: 61
                Version: TLS 1.2 (0x0303)
                Random: 5a292ab7238205b2b8a2e6692abfd518a054515e53cd5b16...
                Session ID Length: 0
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
                Compression Method: null (0)
                Extensions Length: 21
                Extension: server_name (len=0)
                    Type: server_name (0)
                    Length: 0
                Extension: renegotiation_info (len=1)
                    Type: renegotiation_info (65281)
                    Length: 1
                    Renegotiation Info extension
                        Renegotiation info extension length: 0
                Extension: ec_point_formats (len=4)
                    Type: ec_point_formats (11)
                    Length: 4
                    EC point formats Length: 3
                    Elliptic curves point formats (3)
                Extension: SessionTicket TLS (len=0)
                    Type: SessionTicket TLS (35)
                    Length: 0
                    Data (0 bytes)
    

    证书

    Secure Sockets Layer
        TLSv1.2 Record Layer: Handshake Protocol: Certificate
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 3855
            Handshake Protocol: Certificate
                Handshake Type: Certificate (11)
                Length: 3851
                Certificates Length: 3848
                Certificates (3848 bytes)
    

    服务器Hello完成

    Secure Sockets Layer
        TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 589
            Handshake Protocol: Server Key Exchange
                Handshake Type: Server Key Exchange (12)
                Length: 585
                EC Diffie-Hellman Server Params
                    Curve Type: named_curve (0x03)
                    Named Curve: secp256r1 (0x0017)
                    Pubkey Length: 65
                    Pubkey: ...
                    Signature Hash Algorithm: 0x0401
                    Signature Length: 512
                    Signature: ...
    

    多次握手信息

    Secure Sockets Layer
        TLSv1.2 Record Layer: Handshake Protocol: Multiple Handshake Messages
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 77
            Handshake Protocol: Certificate
                Handshake Type: Certificate (11)
                Length: 3
                Certificates Length: 0
            Handshake Protocol: Client Key Exchange
                Handshake Type: Client Key Exchange (16)
                Length: 66
                EC Diffie-Hellman Client Params
                    Pubkey Length: 65
                    Pubkey: ...
        TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
            Content Type: Change Cipher Spec (20)
            Version: TLS 1.2 (0x0303)
            Length: 1
            Change Cipher Spec Message
        TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
            Content Type: Handshake (22)
            Version: TLS 1.2 (0x0303)
            Length: 40
            Handshake Protocol: Encrypted Handshake Message
    

    握手失败

    Secure Sockets Layer
        TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
            Content Type: Alert (21)
            Version: TLS 1.2 (0x0303)
            Length: 2
            Alert Message
                Level: Fatal (2)
                Description: Handshake Failure (40)
    

    更新

    Thx to @ user3484348我现在有更多信息。

    TLS 1.2(正在工作):

    System.Net Information: 0 : [11752] InitializeSecurityContext(
    credential = System.Net.SafeFreeCredential_SECURITY, 
    context = 1054ea8:6091710, 
    targetName = api.company.com, 
    inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
    
    System.Net Information: 0 : [11752] InitializeSecurityContext(
    In-Buffers count=2, 
    Out-Buffer length=0, 
    returned code=IllegalMessage)
    

    TLS 1.0(正常工作):

    System.Net Information: 0 : [11752] InitializeSecurityContext(
    credential = System.Net.SafeFreeCredential_SECURITY, 
    context = 12a5eb0:641d900, 
    targetName = api.company.com, 
    inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
    
    System.Net Information: 0 : [11752] InitializeSecurityContext(
    In-Buffers count=2, 
    Out-Buffer length=0, 
    returned code=ContinueNeeded)
    

    TLS 1.2中的returned codeIllegalMessage,而TLS 1.0则为ContinueNeeded

1 个答案:

答案 0 :(得分:2)

可能您的GetCertificate()返回的证书不是来自Windows证书库。如果您通过添加

来转换应用程序的System.Net调试信息
Integer N = new Integer(n);
N.setValue(7);
print(N); // ok, now it is 7
print(n); // oops, still 6!

到您的.config文件,您将看到" AcquireCredentialsHandle()失败,错误为0X8009030D。"或类似的东西。如果密钥不在MachineKeys系统文件夹中,则System.Net似乎无法使用带私钥的证书。

转到传统路线 - 将证书添加到存储库,授予对密钥文件的访问权限等。