如何在C#中使用HttpWebRequest调用API时禁用CBC密码套件
问题
我使用以下代码片段进行API调用:
if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Tls12) == false) { ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12; } HttpWebRequest webRequest = HttpWebRequest.Create(EndPoint); Token = GetAuthToken(); HttpWebRequest webRequest = HttpWebRequest.Create(EndPoint); // 注:此处存在重复定义的笔误 webRequest.Method = "GET"; webRequest.Accept = "application/vnd.hmrc.1.0+json"; webRequest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + Token); var webResponse = (HttpWebResponse)webRequest.GetResponse(); StreamReader StreamReader = new StreamReader(webResponse.GetResponseStream()); string responseJson = StreamReader.ReadToEnd(); if (webResponse.StatusCode == HttpStatusCode.OK) { // process response }
但近期API主机不再接受CBC密码套件,我该如何修改上述代码以排除CBC密码套件?我已找到一款可通过GUI手动操作的工具IISCrypto,但希望在C#代码中实现该功能,感谢您的协助。
解决方案
1. 全局禁用CBC套件(.NET Framework 4.7+ 推荐)
从.NET Framework 4.7开始,可通过AppContext开关全局禁用所有CBC类型的密码套件,无需手动指定允许列表,代码只需在应用启动时添加一次:
// 放在应用初始化逻辑中,如Program.Main开头 AppContext.SetSwitch("System.Net.DisableCbcCipherSuites", true);
2. 手动指定非CBC密码套件(兼容旧框架/精准控制)
如果你的项目基于.NET Framework 4.6.x及以下,或需要精准控制允许的套件,可替换为HttpClient(HttpWebRequest已被标记为过时)并配置SSL选项:
// 全局初始化HttpClient(建议单例复用) var handler = new SocketsHttpHandler(); // 仅启用TLS 1.2及以上版本 handler.SslOptions.EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13; // 指定允许的非CBC密码套件(示例为常见的GCM/CHACHA20安全套件) handler.SslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_256_GCM_SHA384, TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256, TlsCipherSuite.TLS_AES_128_GCM_SHA256, TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TlsCipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TlsCipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 }); var httpClient = new HttpClient(handler); // 发起请求 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.hmrc.1.0+json")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GetAuthToken()); var response = await httpClient.GetAsync(EndPoint); if (response.IsSuccessStatusCode) { string responseJson = await response.Content.ReadAsStringAsync(); // process response }
注:
CipherSuitesPolicy仅在.NET Framework 4.8+、.NET Core 3.0+支持。
3. 修复原代码的笔误
原代码中重复定义了webRequest,需删除其中一行:
// 删除重复的这行定义 // HttpWebRequest webRequest = HttpWebRequest.Create(EndPoint);
内容的提问来源于stack exchange,提问作者NickSO
相关产品推荐
相关产品推荐

