0

マシン キー コンテナー内のキーを列挙する必要があります。これは通常、オプションのプロバイダー関数ですが、 と の両方MS_STRONG_PROVMS_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