[英]Can a .p12 file with CA certificates be used in C# without importing them to certificate store
我得到了一个包含 3 个证书的.p12 证书文件。 其中2个是CA证书。
如果我使用 curl(Win10 上为 7.70),我可以这样做: curl -s -S -i --cert Swish_Merchant_TestCertificate_1234679304.p12:swish --tlsver "ContentType --p12:swish --tlsv. " https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests --data-binary @jsondata.json
Curl 在连接服务器时会使用 p12 文件中的 CA 证书。
另一方面,如果我尝试在 .net 核心 (3.1) 中执行类似操作,则会失败并显示错误消息“收到的消息意外或格式错误”。
var handler = new HttpClientHandler();
var certs = new X509Certificate2Collection();
certs.Import(@"Swish_Merchant_TestCertificate_1234679304.p12", "swish", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
foreach (var cert in certs)
{
handler.ClientCertificates.Add(cert);
}
var client = new HttpClient(handler);
var url = "https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests";
var request = new HttpRequestMessage()
{
RequestUri = new Uri(url),
Method = HttpMethod.Post,
};
request.Content = new StringContent(System.IO.File.ReadAllText(@"jsondata.json"), Encoding.UTF8, "application/json");
request.Headers.Add("accept", "*/*");
var response = await client.SendAsync(request);
使用 Wireshark 我看到 curl 从 p12 文件发送所有三个证书,而 .net 核心只发送一个。 请参阅下面的图片。
如果我将 CA 证书安装到“当前用户”的“个人证书”中,那么 .net 核心也会发送所有三个证书并且它可以工作。
问题:在使用 .net 内核时,我是否必须安装 CA 证书(到证书库中),或者有没有办法让它的行为就像使用 p12 文件中的证书的 curl 一样?
简短的回答:没有*。
Wordier 介绍: SslStream
从ClientCertificates
集合中选择一个证书,使用 TLS 服务器发送的关于适当根的数据(过去是,但不再普遍)(如果没有适用的根,那么它会选择HasPrivateKey
为真的第一件事)。 在选择过程中,每个候选证书都被单独检查,并要求系统解析链。 在 Windows 上,选定的证书随后被发送到系统库以用于“我们现在正在执行 TLS”,这 (IIRC) 是限制的来源。 (macOS 和 Linux 构建的 .NET 核心只是试图保持行为奇偶性)
一旦选择了证书,就会有最后一个链式遍历来确定要在握手中包含哪些证书,它是在没有来自ClientCertificates
集合的任何其他上下文的情况下完成的。
如果您知道您的集合代表一个链,那么您最好的答案是将 CA 元素导入您的用户 CertificateAuthority 存储。 该存储不会对 CA 证书赋予任何信任,它实际上只是在构建链时使用的缓存。
此外,您不想要 PersistKeySet,并且可能不想要 MachineKeySet:所有不同的 X509KeyStorageFlags 的基本原理是什么?
var handler = new HttpClientHandler();
using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadWrite);
var certs = new X509Certificate2Collection();
certs.Import(@"Swish_Merchant_TestCertificate_1234679304.p12", "swish", X509KeyStorageFlags.DefaultKeySet);
foreach (X509Certificate2 cert in certs)
{
if (cert.HasPrivateKey)
{
handler.ClientCertificates.Add(cert);
}
else
{
store.Add(cert);
}
}
}
var client = new HttpClient(handler);
...
* 如果您的系统已经导入了 CA 链,它可以工作。 或者,如果 CA 链使用授权信息访问扩展来发布 CA 证书的可下载副本,链引擎会找到它,并且一切都会正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.