| ||||
| ||||
Вообщем-то вопрос в теме. Возможно произвести проверку? Если да, то каким способом. | ||||
Ответы: | ||||
| ||||
Конечно, можно. Собственно, например, при установке сертификата кнопкой "Установить личный сертификат" (панель КриптоПро CSP - Сервис) это делается. Вопрос - нужна программная проверка или ручная (когда пользователь хочет увидеть значение открытого ключа из контейнера и сравнить его с ключом из сертификата)? | ||||
| ||||
Есть несколько способов. Например такой: HRESULT WINAPI MatchPublicPrivateKeys( PCCERT_CONTEXT pCertContext, DWORD dwFlags, LPWSTR pwszPin) { PCRYPT_KEY_PROV_INFO pCryptKeyProvInfo = NULL; HCRYPTPROV hProv = 0; DWORD cbData = 0; PCERT_PUBLIC_KEY_INFO pInfo = NULL; CHAR szPin[MAX_PATH]; HRESULT res = S_OK; DWORD provType = 0; dwFlags; if(!CertGetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData)) { res = GetLastError(); DbPrintf ((MODNAME L"!CERT_KEY_PROV_INFO_PROP_ID property\n")); goto ReleaseResource; } pCryptKeyProvInfo = (PCRYPT_KEY_PROV_INFO)malloc(cbData); if (!pCryptKeyProvInfo) { res = ERROR_NOT_ENOUGH_MEMORY; goto ReleaseResource; } if(!CertGetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo, &cbData)) { res = GetLastError(); DbPrintf ((MODNAME L"!CERT_KEY_PROV_INFO_PROP_ID property\n")); goto ReleaseResource; } if (!CryptAcquireContextW ( &hProv, pCryptKeyProvInfo->pwszContainerName, pCryptKeyProvInfo->pwszProvName, pCryptKeyProvInfo->dwProvType, pCryptKeyProvInfo->dwFlags&~CERT_SET_KEY_CONTEXT_PROP_ID)) { res = GetLastError(); DbPrintf ((MODNAME L"!CryptAcquireContextW Failed\n")); goto ReleaseResource; } if (!WideCharToMultiByte( CP_ACP, 0, pwszPin, (int)wcslen (pwszPin) + 1, szPin, MAX_PATH, NULL, NULL)) { res = GetLastError(); DbPrintf ((MODNAME L"!WideCharToMultiByte Failed\n")); goto ReleaseResource; } if (!CryptSetProvParam( hProv, PP_KEYEXCHANGE_PIN, (PBYTE)szPin, 0)) { res = GetLastError(); DbPrintf ((MODNAME L"!CryptSetProvParam Failed\n")); goto ReleaseResource; } cbData = sizeof (DWORD); if (!CryptGetProvParam( hProv, PP_PROVTYPE, (PBYTE)&provType, &cbData, 0)) { res = GetLastError(); DbPrintf ((MODNAME L"!CryptGetProvParam PP_PROVTYPE Failed\n")); goto ReleaseResource; } if (!CryptExportPublicKeyInfo( hProv, pCryptKeyProvInfo->dwKeySpec, pCertContext->dwCertEncodingType, NULL, &cbData)) { res = GetLastError(); DbPrintf ((MODNAME L"!CryptExportPublicKeyInfo Failed\n")); goto ReleaseResource; } pInfo = (PCERT_PUBLIC_KEY_INFO)malloc(cbData); if (!pInfo) { res = ERROR_NOT_ENOUGH_MEMORY; goto ReleaseResource; } if (!CryptExportPublicKeyInfo( hProv, pCryptKeyProvInfo->dwKeySpec, pCertContext->dwCertEncodingType, pInfo, &cbData)) { res = GetLastError(); DbPrintf ((MODNAME L"!CryptExportPublicKeyInfo Failed\n")); goto ReleaseResource; } if (!CertComparePublicKeyInfo ( pCertContext->dwCertEncodingType, pInfo, &pCertContext->pCertInfo->SubjectPublicKeyInfo)) { res = 0x80090015; DbPrintf ((MODNAME L"!key does not match certificate\n")); goto ReleaseResource; } ReleaseResource: if (hProv) CryptReleaseContext(hProv, 0); if (pInfo) free (pInfo); if (pCryptKeyProvInfo) free (pCryptKeyProvInfo); return res; } | ||||
| ||||
или еще вариант - подписать что-нибудь на закрытом ключе, а проверить на ключе сертификата | ||||
| ||||
У меня есть сгенеренный ключ и сертификат *.cer. Нужно однозначно установить их принадлежность друг другу, желательно не через программный код. Просмотр сертификата в контейнере ничего не дает т.к. его там нет. (CryptoPRO CSP 2.0) | ||||
| ||||
Можно воспользоваться утилитой csptest. Для CSP 3.0 эта утилита ставится автоматически в папку установки CSP (по умолчанию \Program Files\Crypto Pro\CSP на системном диске). Если у клиента CSP 2.0, то утилиту можно скачать по ссылке http://www.cryptopro.ru/cryptopro/products/csp/20/csptest-2-0.exe (и в дальнейшем использовать это имя файла) Итак, проверка: 1. экспорт открытого ключа из контейнера в файл: csptest -keyset -container имя -keytype exchange -export key.txt 2. Далее нужно открыть этот файл key.txt на просмотр (F3) в Far или Total Commander и выбрать вид представления – Hex (в Far это F4, в Total – меню Options - Hex) 3. Параллельно открыть файл сертификата – вкладка Состав, поле Открытый ключ. Нужно сравнить последние 64 байта там и там. | ||||
| ||||
Ошибка :963:Error during CryptAcquireContext Error number 80090017 (-2146893801) Тип поставщика не определен. Что сие значит. CryptoPRO на машине установлен. | ||||
| ||||
Добавьте ещё опцию -provtype 75 в строку вызова | ||||