.NET 6 中的 TLS v1.2 密码套件 / GET 请求超时

问题描述 投票:0回答:2

我目前正在尝试连接到至少需要 TLS v1.2 的 AWS REST API。文档统计表明,客户还必须支持具有完美前向保密 (PFS) 的密码套件,例如 Ephemeral Diffie-Hellman (DHE) 或 Elliptic Curve Ephemeral Diffie-Hellman (ECDHE)。

使用

GET
发送
HttpClient
请求时,连接会超时。我已将 TLS 版本明确设置为
TLSv1.2
,如下所示:

httpClientHandler.SslProtocols = SslProtocols.Tls12;

这有效,我可以在 Wireshark 跟踪中看到使用了正确的 TLS 版本。我还确认不存在防火墙问题或类似问题。

工作示例(CURL)

使用cURL时,我可以看到

Sever Hello
响应中的密码套件是
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
,这也是服务器所要求的。

损坏的示例(带有 HttpClient 的 .NET 6)

在.NET 6中使用

HttpClient
时,
Client Hello
中提供了上述密码套件,但服务器响应突然使用
TLS_RSA_WITH_AES_256_GCM_SHA384

我可以看到cURL请求中有额外的扩展,例如

Extension: psk_key_exchange_modes
。对于服务器不接受第一个密码套件的原因有什么解释吗?根据我的理解,第一个提供的密码套件应该是首选,对吗?

有没有办法在.NET 6 中强制使用某种密码套件?

这是我用来重现问题的示例:

public async void PollUrl(string url)
{
    HttpResponseMessage msg = new HttpResponseMessage();

    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

    using HttpClientHandler httpClientHandler = new();

    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true;
    httpClientHandler.SslProtocols = SslProtocols.Tls12;

    using HttpClient client = new(httpClientHandler);

    // This content type is required for the API call
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

    try
    {
        client.Timeout = TimeSpan.FromSeconds(5);
        msg = await client.GetAsync(url);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }

    string stringValue = await msg.Content.ReadAsStringAsync();
    Console.WriteLine(stringValue);
}

该应用程序在 Server 2016 上运行。

c# .net windows amazon-web-services tls1.2
2个回答
2
投票

我们终于找到了原因。 Windows 没有启用所需的密码套件。我们已经使用 IISCrypto 启用了相应的密码套件,现在一切正常了。

看起来可以强制 .NET 使用 TLS 1.2,即使服务器本身未启用它。


0
投票

有没有办法在.NET 6 中强制使用某种密码套件?

我已经在 Ubuntu 上运行的生产环境中尝试过这个。

// Windows OS throws PlatformNotSupportedException for explicit list of TlsCipherSuite
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    httpClientBuilder.ConfigurePrimaryHttpMessageHandler(() =>
    {
        var allowedCipherSuites = Enum.GetValues<TlsCipherSuite>();

        return new SocketsHttpHandler()
        {
            SslOptions = new()
            {
                CipherSuitesPolicy = new CipherSuitesPolicy(allowedCipherSuites)
            }
        };
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.