Мне нужно перечислить ключи в контейнере ключа машины. Хотя это, как правило, необязательная функция провайдера, оба поддерживают MS_STRONG_PROV
и MS_ENH_RSA_AES_PROV
. Я не думаю, что я делаю что-то неправильно или необычно: первый, приобретая дескриптор контекста с CryptAcquireContext(... CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT ...)
, затем вызывая CryptGetProvParam(... PP_ENUMCONTAINERS ...)
несколько раз, пока перечисление не исчерпывается:Медленное перечисление ключей в машине Контейнер ключей RSA
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 мс. 440 мс - это проблема производительности для меня.
Пожалуйста, не связывайтесь с внешним сайтом. Если код важен для вашего вопроса (и это обычно есть), поместите его в свой вопрос. – IInspectable
@Inpectable: Спасибо, я не знал, что ссылки не были разрешены в вопросах. Фактически SO даже представляет кнопку «вставить ссылку» при запросе. Если вы можете дать мне указатель на правило, я был бы признателен. Но в основном, я разорван. На самом деле это 60-минутная программа, и вы можете сказать, что в ней нет ничего существенного: «Я перечисляю ключи так, как это должно было быть», но должен вызывать «показать мне хотя бы некоторые из ваш код «последующий»); с другой стороны, все это необходимо для быстрого воспроизведения. Не могли бы вы посоветовать опубликовать полный источник в вопрос? – kkm
Ссылка на внешний контент строго запрещена. Тем не менее, вопросы о stackoverflow должны быть самодостаточными. Если внешний ресурс станет временно недоступным или исчезнет навсегда, вопрос может перестать быть полезным. Руководства можно найти в разделе [Как задать хороший вопрос?] (Http://stackoverflow.com/help/how-to-ask) Я бы рекомендовал добавить весь исходный код, с которым вы сейчас связываетесь. Эффект, который вы наблюдаете, может быть вызван или не вызван вашим кодом. Не видя кода, сложнее дать хорошие ответы. – IInspectable