29.10.2001 13:28:10Диалог с паролем Ответов: 3
Vladimir
Добрый день.
Хотелось бы узнать, есть ли возможность при расшифровке с помощью CryptDecryptMessage нескольких сообщений выдавать диалог с паролем только один раз, в начале? Тоже самое интересует для случая подписывания нескольких сообщений.
 
Ответы:
29.10.2001 16:55:26Игорь Курепкин
Вот именно для CryptDecrypt сказать затрудняюь.
Для функций Simlified и Low Level это делается (кэширование) через флаг в контексте сертификата и это есть в примерах.
/*--------------------------------------------------------------------*/
/* Для того чтобы функция CryptAcquireContext не загружала постоянно*/
/* провайдер и ключ можно использовать флаг CERT_SET_KEY_CONTEXT_PROP_ID или*/
/* CERT_SET_KEY_PROV_HANDLE_PROP_ID в значении флага структуры CRYPT_KEY_PROV_INFO.*/
/**/
/* Для этого определим наличие этого свойства и перезапишем флаг*/
ret = CertGetCertificateContextProperty(pUserCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData);
if (ret) {
pCryptKeyProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(cbData);
if(!pCryptKeyProvInfo)
HandleErrorFL("Error in allocation of memory.");

ret = CertGetCertificateContextProperty(pUserCert,CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo,&cbData);
if (ret)
{
/* Установим флаг кеширования провайдера*/
pCryptKeyProvInfo->dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
/* Установим свойства в контексте сертификата*/
ret = CertSetCertificateContextProperty(pUserCert, CERT_KEY_PROV_INFO_PROP_ID,
CERT_STORE_NO_CRYPT_RELEASE_FLAG, pCryptKeyProvInfo);
free(pCryptKeyProvInfo);
}
else
HandleErrorFL("The property was not retrieved.");
}
else {
printf ("Cannot retrive certificate property.\n");
}
29.10.2001 17:06:13Игорь Курепкин
Немного перепутал.
Как раз для CryptDecryptMessage и CryptSignMessage и используется флаг кэширования в контексте сертификата.
Будет работать, если конечно контекст сертификат не удаляется.
23.04.2002 18:11:18ak
День добрый. Никак не могу добиться чтобы пароль запрашивался один раз (для м 1.2). Делаю так:
hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0,0,
CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG| CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");

certContext = CertFindCertificateInStore (
hCertStore,
MY_ENCODING,
0,
CERT_FIND_SUBJECT_STR,
wstrSubject,
NULL);

ret = CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData);
if (ret) {pCryptKeyProvInfo = CRYPT_KEY_PROV_INFO *)malloc(cbData);
if(pCryptKeyProvInfo) {
ret = CertGetCertificateContextProperty(certContext,CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo, &cbData);
if (ret) { pCryptKeyProvInfo->dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;

ret = CertSetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID,
CERT_STORE_NO_CRYPT_RELEASE_FLAG, pCryptKeyProvInfo);

этот вызов возвращает FALSE !
GetLastError() дает 80070005 (E_ACCESSDENIED)

Посоветуйте, плиз, что-нибудь