gpt4 book ai didi

.net - Windows 10 通用应用程序中的证书固定

转载 作者:行者123 更新时间:2023-12-04 15:32:38 25 4
gpt4 key购买 nike

我需要一种在 Windows 10 通用应用程序中实现证书或公钥固定的好方法。所有代码都在 C# 中,所有连接都是 HTTPS,所以 Windows.Web.Http.HttpClient 类的东西会很棒。是否有一个简单的类/库,或者至少是一个分步指南,用于如何实现这些东西,这些东西可以由不知道 X.509 证书的神秘细节的人安全地完成等等?

我发现一些关于使用 native 代码或 OpenSSL 等第三方库的内容(非常复杂!)。我发现的最好的东西是 this question 关于在 WP8.0 中的固定,其中包括一个应该适用于 WP8.1 并希望也适用于 Win10 的代码示例,但它有点丑陋和令人困惑,我不知道如何要求发送带有敏感信息的请求时,服务器的证书是固定的证书之一。由于检查时间/使用时间 (TOCTOU) 攻击,事先检查似乎并不安全(除非 HttpRequestMessage . TransportInformation 函数打开连接然后将其保持打开状态,因此攻击者没有机会获得人-在新连接的中间位置)。理想情况下,有一种过滤 HttpClient 的方法,因此它只连接到带有固定证书的服务器,但我能找到的最接近的东西恰恰相反(忽略某些证书错误,如 here 所述)通过 HttpBaseProtocolFilter.IgnorableServerCertificateErrors 属性,它似乎没有任何限制有效证书的选项。

有人在这里有好的解决方案吗?如果 HttpRequestMessage.TransportInformation 方法(使用自定义证书验证代码)是唯一的选择,那么在发送请求之前检查该属性是否可以安全地抵御 TOCTOU 攻击?

最佳答案

你看过 HttpBaseProtocolFilter 的 ServerCustomValidationRequested 事件了吗?对我来说,棘手的部分是从 Certificate 对象中提取公共(public)证书。为此,我必须引入 System.Security.Cryptography.X509Certificates nuget 包。我的代码如下所示:

private void DoIt()
{
using (var filter = new HttpBaseProtocolFilter())
{
filter.ServerCustomValidationRequested += FilterOnServerCustomValidationRequested;
var httpClient = new Windows.Web.Http.HttpClient(filter);
var myString = await httpClient.GetStringAsync(new Uri("https://myserver.com"));
// I guess we should be kind and unsubscribe?
filter.ServerCustomValidationRequested -= FilterOnServerCustomValidationRequested;
}
}

private void FilterOnServerCustomValidationRequested(HttpBaseProtocolFilter sender, HttpServerCustomValidationRequestedEventArgs args)
{
if (!IsCertificateValid(args.RequestMessage, args.ServerCertificate, args.ServerCertificateErrors))
{
args.Reject();
}
}

private bool IsCertificateValid(Windows.Web.Http.HttpRequestMessage httpRequestMessage, Certificate cert, IReadOnlyList<ChainValidationResult> sslPolicyErrors)
{
// disallow self-signed certificates or certificates with errors
if (sslPolicyErrors.Count > 0)
{
return false;
}

if (RequestRequiresCheck(httpRequestMessage.RequestUri))
{
var certificateSubject = cert?.Subject;
bool subjectMatches = certificateSubject == CERTIFICATE_COMMON_NAME;

var certArray = cert?.GetCertificateBlob().ToArray();
var x509Certificate2 = new X509Certificate2(certArray);
var certificatePublicKey = x509Certificate2.GetPublicKey();
var certificatePublicKeyString = Convert.ToBase64String(certificatePublicKey);
bool publicKeyMatches = certificatePublicKeyString == CERTIFICATE_PUBLIC_KEY;

return subjectMatches && publicKeyMatches;
}

return true;
}

private bool RequestRequiresCheck(Uri uri)
{
return uri.IsAbsoluteUri &&
uri.AbsoluteUri.StartsWith("https://", StringComparison.CurrentCultureIgnoreCase) &&
uri.AbsoluteUri.StartsWith(BASE_URL, StringComparison.CurrentCultureIgnoreCase);
}

p.s.我最终写了一个 blog post如果您对更多详细信息感兴趣,请了解 UWP 中的证书固定

关于.net - Windows 10 通用应用程序中的证书固定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34667158/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com