0

我需要枚举机器密钥容器中的密钥。虽然这通常是一个可选的提供程序功能,但两者都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 倍。任何指针?

我将测试的全部来源放入 Gist。该测试在没有任何加密硬件的非常通用的 Windows 7 机器上运行。

补充:在 Server 2012 HyperV 主机上的 Server 2012 虚拟机上,减速因素甚至更大,超过 130:440 对 3.3 毫秒。确实,440ms 对我来说是一个性能问题。

4

1 回答 1

0

是否与Microsoft的此问题有关:

当您在 Windows Server 2008 R2 或 Windows 7 中调用 CryptAcquireContext 函数时,您会遇到性能不佳

来自问题:“此问题是由于 Windows Server 2008 R2 和 Windows 7 中的 CryptAcquireContext 函数发生更改而发生的。

此更改检查函数是否在域环境中运行。但是,该过程非常耗时,并导致 CryptAcquireContext 函数的运行时间增加。”

于 2017-05-29T12:03:15.820 回答