限制C#中密码套件的编程方法

时间:2019-07-24 23:46:14

标签: c# .net ssl encryption

我的C#程序正在使用TLS 1.2调用外部API。

这是我将其限制为TLS 1.2的方式

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

此外,API进一步将密码套件限制为遵循

  

密码套件

     

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

我进行了进一步的研究,发现可以通过更改运行计算机上的网络配置来实现。

https://www.c-sharpcorner.com/forums/change-cipher-suitetlsecdheecdsawithaes256gcmsha384

但是我的机器上有多个程序(在不同的外部方)调用不同的API,因此我想避免在机器级别进行全局更改。有什么办法可以通过编程方式限制密码列表?

1 个答案:

答案 0 :(得分:2)

对于那些仍然在为这个问题而苦苦挣扎的人。

我遇到了同样的问题,我的自动测试 (dotnetcore3.1) 在 WS 2012 R2 机器上运行,我必须调用仅接受两个密码套件的第三方 API:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)。

C# HttpClient 依赖于主机系统中的密码套件,而 Chrome、Firefox 和 Curl 则有自己的安全和加密系统。 WS 2012 R2 没有这两个密码,我不知道如何将它们添加到机器中,这些密码没有 Windows 更新。

我选择使用非常酷的 Nuget 数据包 CurlThin 作为解决方案。使用它我们可以为请求设置我们自己的密码套件,所以我们不需要对服务器端做任何事情。

我安装了两个数据包:CurlThin 本身和 CurlThin.Native
带有标头的 GET 请求到 HTTPS 端点的结果代码如下所示:

using CurlThin;
using CurlThin.Enums;
using CurlThin.Helpers;
using CurlThin.Native;
using CurlThin.SafeHandles;
using System.Text;

        private static string GetToken()
        {
            //This string is for extracting libcurl and ssl libs to the bin directory.
            CurlResources.Init();
            var global = CurlNative.Init();
            var easy = CurlNative.Easy.Init();
            string content;

            try
            {
                var dataCopier = new DataCallbackCopier();

                CurlNative.Easy.SetOpt(easy, CURLoption.URL, "https://someendpoints.net/thatendpoint?fake=true");
                CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, dataCopier.DataHandler);
                //This string is needed when you call a https endpoint.
                CurlNative.Easy.SetOpt(easy, CURLoption.CAINFO, CurlResources.CaBundlePath);

                var headers = CurlNative.Slist.Append(SafeSlistHandle.Null, "Authorization: Bearer blablabla");
                CurlNative.Easy.SetOpt(easy, CURLoption.HTTPHEADER, headers.DangerousGetHandle());
                //Your set of ciphers, full list is here https://curl.se/docs/ssl-ciphers.html
                CurlNative.Easy.SetOpt(easy, CURLoption.SSL_CIPHER_LIST, "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256");

                CurlNative.Easy.Perform(easy);

                content = Encoding.UTF8.GetString(dataCopier.Stream.ToArray());
            }
            finally
            {
                easy.Dispose();

                if (global == CURLcode.OK)
                    CurlNative.Cleanup();
            }
            return content;
        }

希望有人会觉得它有帮助。谢谢:)