- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我开发了一个 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 调用有关,但我找不到链接。
我真的在寻找:
感谢您的帮助。
最佳答案
这个问题现在已经解决了,我想我明白为什么了!
当您使用私钥加载 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/
我们想在应用商店中发布一个应用。为我们构建它的第 3 方需要我们通过苹果开发门户创建的证书和配置文件。根据文档,创建证书的方法是使用 mac 的钥匙串(keychain)应用程序,然后选择“从证书颁发
我正在尝试使用 Java Http 客户端连接到服务器以进行 Web 服务调用。如果我用下面的代码打开网络调试.. System.setProperty("javax.net.debug", "all
我在尝试推送我的更改时才开始收到此错误。我不知道我的系统发生了什么变化,并且在这方面不应该有任何自签名证书。 Git 已卸载并重新安装。 Git 似乎使用了正确的包: http.sslcainfo=C
除非我设置以下内容,否则我会收到上述错误: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 这是不安全的,违背了 SSL 的目的。 我已经从 http
我有一个基于 Linux 的 Docker 容器,如果我这样做: curl https://google.com ...然后我得到一个错误: curl: (60) SSL certificate pr
我想在我的 Linux 计算机上安装 nvm。(我的 Debian 版本是 10,Git 版本是 2.27。OPENSSL 版本是 1.1.1d 2019 年 9 月 10 日) 我阅读了这份文件 h
我正在使用 Symfony 5,我需要使用 composer 安装 'knplabs/knp-snappy-bundle' 但我有这个消息: [Composer\Downloader\Transpor
我已经通过 VSTS 部署我的应用程序一段时间了,然后突然出现此错误: 无法访问 SSL 证书问题:(url) 证书链中的自签名证书。 为什么突然发生这种情况,我该如何解决? 更新:我注意到我有一个新
我正在尝试使用安全性配置 WCF 服务。我生成了 2 个存储在 LocalComputer\Personal Certificates 中的证书(用于服务器和客户端)。我的配置是: 服务器:
我正在创建连接到的 Azure 函数来执行 PnP 命令。我已经创建了 docs 中提到的证书。我总是收到Cannot findcertificate with this指纹在证书存储中。Except
美好的一天,我是服务器设置的新手。我目前正在使用 laravel 5.4 来集成我的 quickbooks app在我的实时服务器上 http://qb.dagnum.com/connect但我继续收
我正在尝试从 Github 克隆一个项目但我无法克隆它,因为我有这个错误 无法访问:SSL 证书问题:证书链中的自签名证书 我可以从我的网络访问并且我有证书。 我的Android Studio有什么问
我正在尝试使用 AWS-CLI 检索 aws elasticbeanstalk 详细信息,但出现以下错误。 错误信息: C:\abdul>aws elasticbeanstalk describe-e
我实际上正在阅读有关证书和证书链的内容。我了解证书是由实体的私钥签名的一段数据,只能使用给定实体(例如根 CA)的公钥解密。 但是,我在几个地方看到“证书签署另一个证书”(例如:Microsoft I
我想默认“接受”新证书。我尝试了以下方法。 $ dpkg-reconfigure -f noninteractive ca-certificates 它运行,但没有添加 CA。 如果不行,直接修改/e
有人通过AWS Certificate Manager为他们的域名购买了通配符证书,我需要将其转移到Heroku,以获取使用域名子域名的应用程序。 无论是通过AWS控制台还是通过其CLI,我都找不到如
我可以通过重新启动我的 Windows 7 来运行 selenium 服务器。但是,如果我终止服务器并再次启动它,我将收到此错误。有时执行 webdriver-manager update--igno
我在 IE9 中遇到安全证书问题。 然后我去我得到的特定地址 There is a problem with this website's security certificate. 如何避免出现此窗
应用签名证书和上传证书有什么区别? 我在将 Google Play 游戏与我的应用程序集成时遇到了问题(我将此作为另一个问题发布),我注意到用于在 Google API 控制台上自动生成的客户端 ID
我正在尝试在 Mac 上使用 Heroku CLI。 当我尝试使用 Heroku login 登录 Heroku 并提供我的凭据时,出现以下错误: Error: self signed certifi
我是一名优秀的程序员,十分优秀!