28.05.2001 10:58:44CALG_DH_EX OID и CryptGetUserKey Ответов: 0
Алексей Алексеев
Здравствуйте!

Был бы очень благодарен, если кто-нибудь поможет мне с двумя проблемами.

Проблема 1.

Я выполняю следующую последовательность действий:

HCRYPTPROV hContext;
HCRYPTKEY hExchangeKey;

CryptAcquireContext(&hContext, "TEST1", CP_DEF_PROV, PROV_GOST_DH, CRYPT_NEWKEYSET);

// Генерируем ключ Diffie-Hellman-а
CryptGenKey(hContext, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hExchangeKey);

CERT_PUBLIC_KEY_INFO *pInfo = (PCERT_PUBLIC_KEY_INFO)new byte [1000];
DWORD cbPublicKeyInfo = 1000;

// Получаем информацию о его открытой части
CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pInfo , &cbPublicKeyInfo);

// Смотрим, что за алгоритм
printf(pInfo->Algorithm.pszObjId);

В результате ожидаю получить "1.2.643.2.2.99" (szOID_CP_DH_EX), а получаю
"1.2.643.2.2.20", т.е. szOID_CP_GOST_R3410.

В чем я не прав?



Проблема 2:

У меня есть два чистых контейнера. В первом я генерирую ключ для обмена ключами (CALG_DH_EX) и экспортирую его как PRIVATEKEYBLOB.
Потом импортирую этот ключ во второй контейнер и пытаюсь получить его handle вызовом

CryptGetUserKey(hContext, AT_KEYEXCHANGE, &hUserKey);

Получаю ошибку NTE_NO_KEY.

Если делать все то же самое, но для ключей подписи (т.е. указать при генерации CALG_GR3410), а в CryptGetUserKey - AT_SIGNATURE, то все работает.

Что делать?

Заранее огромное спасибо.

PS. Тестовый код, который я использую во втором случае, приведен ниже.

char pszPassword[] = "12345678";
byte pbIV[8];
DWORD dwIVSize = 8;

HCRYPTPROV hContext;
CryptAcquireContext(&hContext, "TEST1", CP_DEF_PROV, PROV_GOST_DH, CRYPT_NEWKEYSET);

// Получение ключа шифрования ключевого блоба
HCRYPTHASH hHash;
CryptCreateHash(hContext, CALG_GR3411, 0, 0, &hHash);
CryptHashData(hHash, (byte *)pszPassword, 8, 0);
HCRYPTKEY hKeyEncodeKey;
CryptDeriveKey(hContext, CALG_G28147, hHash, CRYPT_EXPORTABLE, &hKeyEncodeKey);

// Создание ключа
HCRYPTKEY hExchangeKey;
CryptGenKey(hContext, CALG_DH_EX, CRYPT_EXPORTABLE, &hExchangeKey);

// Экспорт ключа
byte pbKeyBlob[1000];
DWORD dwKeyBlobSize = 1000;
CryptGetKeyParam(hKeyEncodeKey, KP_IV, pbIV, &dwIVSize, 0);
CryptExportKey(hExchangeKey, hKeyEncodeKey, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwKeyBlobSize);

// Очистка переменных пропущена...

CryptAcquireContext(&hContext, "TEST2", CP_DEF_PROV, PROV_GOST_DH, CRYPT_NEWKEYSET);

// Получение ключа шифрования ключевого блоба
CryptCreateHash(hContext, CALG_GR3411, 0, 0, &hHash);
CryptHashData(hHash, (byte *)pszPassword, 8, 0);
CryptDeriveKey(hContext, CALG_G28147, hHash, CRYPT_EXPORTABLE, &hKeyEncodeKey);
CryptSetKeyParam(hKeyEncodeKey, KP_IV, pbIV, 0);

CryptImportKey(hContext, pbKeyBlob, dwKeyBlobSize, hKeyEncodeKey, CRYPT_EXPORTABLE, &hExchangeKey);

HCRYPTKEY hUserKey;
CryptGetUserKey(hContext, AT_KEYEXCHANGE, &hUserKey);
DWORD dwError = GetLastError();

// dwError == NTE_NO_KEY

// Очистка переменных пропущена...