我需要枚举机器密钥容器中的密钥。虽然这通常是一个可选的提供程序函数,但MS_STRONG_PROV
和MS_ENH_RSA_AES_PROV
都支持它。我不认为我做错了什么或不正常:首先,使用CryptAcquireContext(... CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT ...)
获取上下文句柄,然后反复调用CryptGetProvParam(... PP_ENUMCONTAINERS ...)
,直到枚举用尽:
void enum_keys(HCRYPTPROV hprov) {
BYTE buf[1024]; // Max key name length we support.
for (DWORD first_next = CRYPT_FIRST; 1; first_next = CRYPT_NEXT) {
DWORD buf_len = sizeof buf;
if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, buf, &buf_len, first_next)) {
if (GetLastError() == ERROR_NO_MORE_ITEMS) break;
else exit(1);
}
}
}
void do_benchmark(DWORD enum_flags) {
enum_flags |= CRYPT_VERIFYCONTEXT;
HCRYPTPROV hprov;
if (!CryptAcquireContext(&hprov, NULL, MS_ENH_RSA_AES_PROV_A,
PROV_RSA_AES, enum_flags))
exit(1);
int K = 100;
ClockIn(); // Pseudocode
for (int i = 0; i < K; ++i)
enum_keys (hprov);
ClockOut(); // Pseudocode.
printf(" %f ms per pass\n", TimeElapsed() / K);
CryptReleaseContext(hprov, 0);
}
void main() {
printf("--- User key store access performance test... ");
do_benchmark(0);
printf("--- Machine key store access performance test... ");
do_benchmark(CRYPT_MACHINE_KEYSET);
}
为了对枚举进行基准测试,我将离开上下文并释放出循环,并仅计算枚举,并重复枚举100次。我注意到,对于普通用户而言,枚举比管理员慢得多。当我以自己的身份运行测试时(启用了UAC的管理员的成员),我正在
--- User key store access performance test... 3.317211 ms per pass
--- Machine key store access performance test... 78.051593 ms per pass
但是,当我从提升的提示中运行相同的测试时,结果会大不相同:
--- User key store access performance test... 3.279580 ms per pass
--- Machine key store access performance test... 1.499939 ms per pass
在幕后,向管理员报告的密钥多于向非管理员用户报告的密钥,但这是预期和正常的。我不明白为什么非管理员用户的枚举速度慢约40倍。有什么指针吗?
我正在填写source of my test into a Gist。该测试在一台非常通用的Windows 7机器上运行,没有任何加密硬件。
已添加:在Server 2012 HyperV主机上的Server 2012虚拟机上,减速因子甚至更高,超过130:440与3.3毫秒。事实上,440ms对我来说是一个性能问题。
答案 0 :(得分:0)
是否与Microsoft的此问题有关:
从问题: &#34;出现此问题的原因是Windows Server 2008 R2和Windows 7中的CryptAcquireContext函数发生了更改。
此更改检查该功能是否在域环境中运行。但是,该过程非常耗时,并导致CryptAcquireContext函数的运行时间增加。&#34;