2015-09-11 5 views
0

Мне нужно перечислить ключи в контейнере ключа машины. Хотя это, как правило, необязательная функция провайдера, оба поддерживают 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 мс - это проблема производительности для меня.

+0

Пожалуйста, не связывайтесь с внешним сайтом. Если код важен для вашего вопроса (и это обычно есть), поместите его в свой вопрос. – IInspectable

+0

@Inpectable: Спасибо, я не знал, что ссылки не были разрешены в вопросах. Фактически SO даже представляет кнопку «вставить ссылку» при запросе. Если вы можете дать мне указатель на правило, я был бы признателен. Но в основном, я разорван. На самом деле это 60-минутная программа, и вы можете сказать, что в ней нет ничего существенного: «Я перечисляю ключи так, как это должно было быть», но должен вызывать «показать мне хотя бы некоторые из ваш код «последующий»); с другой стороны, все это необходимо для быстрого воспроизведения. Не могли бы вы посоветовать опубликовать полный источник в вопрос? – kkm

+2

Ссылка на внешний контент строго запрещена. Тем не менее, вопросы о stackoverflow должны быть самодостаточными. Если внешний ресурс станет временно недоступным или исчезнет навсегда, вопрос может перестать быть полезным. Руководства можно найти в разделе [Как задать хороший вопрос?] (Http://stackoverflow.com/help/how-to-ask) Я бы рекомендовал добавить весь исходный код, с которым вы сейчас связываетесь. Эффект, который вы наблюдаете, может быть вызван или не вызван вашим кодом. Не видя кода, сложнее дать хорошие ответы. – IInspectable

ответ

0

Может ли это быть связано с этим вопросом от Microsoft:

You experience poor performance when you call the CryptAcquireContext function in Windows Server 2008 R2 or in Windows 7

Из выпуска: «Эта проблема возникает из-за изменения функции CryptAcquireContext в Windows Server 2008 R2 и в Windows 7.

Это изменение проверяет, работает ли функция в среде домена. Однако этот процесс занимает много времени и увеличивает время работы функции CryptAcquireContext. "