gpt4 book ai didi

c# - X509Certificate 构造函数需要 >6 秒才能为特定用户执行

转载 作者:太空宇宙 更新时间:2023-11-03 14:46:36 26 4
gpt4 key购买 nike

我开发了一个 C#、.NET4.5.2 客户端/服务器系统,它使用 TLS/SSL 进行通信。证书是从文件加载的。我使用“MakeCert”实用程序创建了证书文件以创建一个 .pvk 和 .cer 文件,然后我使用“pvk2pfx”实用程序将它们组合成一个 .pfx。

要使用证书,我通过使用 X509Certificate2 构造函数和重载来加载它们,以将文件路径和密码作为字符串传递:

X509Certificate2(string filePath, string password)

我注意到随着时间的推移,证书的加载变得非常缓慢。我不确定是否存在使它们变慢的“事件”,或者它是否是渐进的,但现在最多需要大约 6 秒来加载 PFX 文件。加载 CER 文件没有问题,大约需要 0.1 秒。

我运行的是 Windows 8.1,问题仅出在笔记本电脑上的用户登录上。

我编写了以下测试应用程序来验证问题:

    private const string filePath = @"c:\testcert.pfx";
private const string password = "testpassword";
static void Main(string[] args)
{
var stopwatch = new Stopwatch();
try
{
Console.WriteLine("About to create certificate. Press Enter.");
Console.ReadLine();

stopwatch.Start();
var cert = new X509Certificate(filePath, password);
stopwatch.Stop();

Console.WriteLine(stopwatch.Elapsed);
Console.WriteLine("Certificate created. About to reset. Press Enter.");
Console.ReadLine();

cert.Reset();

Console.WriteLine("Certificate reset. Press Enter.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}

我让一些同事在他们的 PC 上运行该程序。我还尝试在 VM 中运行,然后在我自己的笔记本电脑上设置一个新用户。在所有情况下,它都在 ~0.1 秒内运行,但对于我的普通用户登录,它在 >6 秒内运行。

起初我没有在证书上调用“Reset()”,所以我认为可能某处的一些临时文件有问题,所以我使用 procmon 来找出发生了什么。我确定在以下目录中创建了一些临时文件(尽管在应用程序退出时即使没有调用 Reset() 也会整理它们):

C:\Users\<username>\AppData\Roaming\Microsoft\Crypto\RSA\<SID>

只是为了确保我已尝试删除此目录中的文件,但没有任何区别。

使用 procmon 我可以看到在加载证书期间文件/注册表事件中有 2 个间隙,这在加载速度很快的系统中不会发生。首先是在它尝试使用“dpapi.dll”之后。第二个是在读取以下“C:\Extend\$UsnJrnl:$J:$DATA”之后。 DPAPI.dll 是 Windows 数据保护的接口(interface)。后一个文件是 NTFS 的 USN 日志,它记录文件更改。我在这两个方面都不是专家,我不确定两者是否相关!

然后我尝试使用 API Monitor http://www.rohitab.com/apimonitor观察系统调用。同样,我不是专家,但我仔细查看了暂停前发生的情况。我不明白其中有很多内容可能相关也可能不相关,我欢迎对其中的任何内容发表评论以帮助集中解决问题。

2 秒间隔之前的最后一次调用是一个具有以下调用堆栈的 memcpy:

#   Module  Address Offset  Location
1 RPCRT4.dll 0x74f6378b 0x2378b I_RpcSendReceive + 0x1bb
2 RPCRT4.dll 0x74f6367b 0x2367b I_RpcSendReceive + 0xab
3 RPCRT4.dll 0x74f594df 0x194df NdrServerInitializeNew + 0x83f
4 RPCRT4.dll 0x74f63619 0x23619 I_RpcSendReceive + 0x49
5 RPCRT4.dll 0x74f6398b 0x2398b NdrSendReceive + 0x2b

更高的潜在有趣行似乎是:

#   Time of Day Thread  Module  API Return Value    Error   Duration
64922 6:38:44.348 AM 1 DPAPI.dll SystemFunction040 ( 0x00ac5a30, 8, RTL_ENCRYPT_OPTION_SAME_LOGON ) STATUS_SUCCESS 0.0000402
64923 6:38:44.349 AM 1 CRYPTBASE.dll RtlInitUnicodeString ( 0x0090e5a8, "\Device\KsecDD" ) 0.0000004

64949 6:38:44.349 AM 1 RPCRT4.dll RtlInitUnicodeString ( 0x0090e0b0, "\RPC Control\protected_storage" ) 0.0000000

我发现很难追踪调用堆栈,但我认为这些最终来自一个名为 CryptQueryObject 的函数。

我找到了以下可能相关的文章,但它不是 Windows8.1。我删除了 %windir%\Temp 文件夹以防万一,但也无济于事。

https://support.microsoft.com/en-gb/kb/931908

我记得在某处找到一篇文章,指出延迟可能与来自 CryptQueryObject 的 ActiveDirectory 调用有关,但我找不到链接。

我真的在寻找:

  1. 如何修复我的用户登录以便加载证书不需要 6 秒
  2. 如何确保我的代码是正确的,这样它就不会再次发生或发生在使用该系统的其他人身上

感谢您的帮助。

最佳答案

这个问题现在已经解决了,我我明白为什么了!

当您使用私钥加载 X509Certificate 时,Windows 会将 key 存储到文件中并使用“数据保护”加密该文件(因此我监控了对 DPAPI 的调用)。

https://technet.microsoft.com/en-us/library/cc962112.aspx

用于加密文件的 key 称为“主 key ”。它基于您的用户登录,并在您更改使用密码时更新。它还会在 90 天后自动过期。

http://www.passcape.com/index.php?section=docsys&cmd=details&id=28#33

如上面链接所述,主 key 存储在以下目录中:

%APPDATA%/Microsoft/Protect/%SID%

通过查看该目录中文件的“最后修改”日期,我可以看出我的 MasterKey 实际上已经超过 90 天了。因此,每当我加载证书时,它都会尝试将私钥存储在加密文件中,并注意到主 key 已过期,因此它会尝试更新它。

我重新运行了 ProcMon,但停止了仅从我的测试应用程序过滤事件。然后我可以看到,在“间隙”期间,一个名为 lsass.exe 的进程对我们的 Active Directory 服务器进行了许多 UDP 调用,该进程与安全和密码更新有关(由于堆栈溢出,无法发布另一个链接限制但易于搜索)。

我认为尝试更新主 key 的过程必须涉及与 ActiveDirectory 服务的一些交互。

我远程工作并通过 VPN 连接到我的工作网络。 VPN 不允许访问 ActiveDirectory 服务器,因此我认为延迟是由于尝试访问该服务器但失败造成的。

我一直等到下次访问办公室时,一旦连接到网络并可以访问 ActiveDirectory 服务器,加载证书的延迟就消失了。我确认我的 MasterKey 文件也已更新,不再过时。

我在通过 VPN 连接时重新测试了加载证书,延迟仍然存在,所以这似乎确实可以确认只要主 key 没有过期就可以。

不幸的是,由于同样无法访问 Active Directory 服务的问题,我无法通过 VPN 更改密码。

我的问题解决了。我很欣赏它可能相当独特,但我希望我的调查细节在某些时候对其他人有所帮助!

关于c# - X509Certificate 构造函数需要 >6 秒才能为特定用户执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38466999/

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