| ||||
| ||||
Есть пример из MSDN: === code snippet start === //-------------------------------------------------------------------- // This example program creates a session key and a simple key // BLOB holding that session key. The key BLOB can be written to disk // and later read from a disk file. #include <stdio.h> #include <windows.h> #include <wincrypt.h> #include "WinCryptEx.h" void MyHandleError(char *s); int main(void) { //-------------------------------------------------------------------- // Declare and initialize variables. HCRYPTPROV hProv; // CSP handle HCRYPTKEY hSignKey; // Signature key pair handle HCRYPTKEY hXchgKey; // Exchange key pair handle HCRYPTKEY hKey; // Session key handle BYTE *pbKeyBlob; // Pointer to a simple key BLOB DWORD dwBlobLen; // The length of the key BLOB //-------------------------------------------------------------------- // Acquire a cryptographic provider context handle. if(CryptAcquireContext( &hProv, "qqqq", NULL, 71, 0)) { printf("The CSP has been acquired. \n"); } else { MyHandleError("Error during CryptAcquireContext."); } //-------------------------------------------------------------------- // Get a handle to the key exchange key. if(CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hXchgKey)) { printf("The key exchange key has been acquired. \n"); } else { printf("Error during CryptGetUserKey exchange key."); } // hSignKey may be used to verify a signature. hXchgKey will be used // to export a session key. //-------------------------------------------------------------------- // Generate a session key. if (CryptGenKey( hProv, CALG_G28147, CRYPT_EXPORTABLE, &hKey)) { printf("Original session key is created. \n"); } else { MyHandleError("ERROR -- CryptGenKey."); } // Determine the size of the key BLOB and allocate memory. if(CryptExportKey( hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwBlobLen)) { printf("Size of the BLOB for the session key determined. \n"); } else { MyHandleError("Error computing BLOB length."); } if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) { printf("Memory has been allocated for the BLOB. \n"); } else { MyHandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Export the key into a simple key BLOB. if(CryptExportKey( hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwBlobLen)) { printf("Contents have been written to the BLOB. \n"); } else { MyHandleError("Error during CryptExportKey."); } //-------------------------------------------------------------------- // At this point, other processing such as writing the key BLOB to // a file could be done. FILE *F = fopen("test.dat", "wb"); if (!F) return 11; if (fwrite(pbKeyBlob, dwBlobLen, 1, F) != 1) return 12; fclose(F); //-------------------------------------------------------------------- // After all processing, clean up. //-------------------------------------------------------------------- // Free the memory used by the key BLOB. free(pbKeyBlob); // Destroy the session key. if(hKey) CryptDestroyKey(hKey); // Destroy the signature key handle. if(hSignKey) CryptDestroyKey(hSignKey); // Destroy the key exchange key handle. if(hXchgKey) CryptDestroyKey(hXchgKey); // Release the provider handle. if(hProv) CryptReleaseContext(hProv, 0); printf("The program ran to completion without error. \n"); }// End of main //-------------------------------------------------------------------- // This example uses the function MyHandleError, a simple error // handling function, to print an error message and exit // the program. // For most applications, replace this function with one // that does more extensive error reporting. void MyHandleError(char *s) { printf("An error occurred in running the program.\n"); printf("%s\n",s); printf("Error number %x\n.",GetLastError()); printf("Program terminating.\n"); exit(1); } === code snippet end === Контейнер "qqqq" существует, ключ обмена в нем имеется. Первый же вызов CryptExportKey (для определения длины BLOB’а) возвращает NTE_BAD_KEY_STATE. Про какой из ключей это сообщается и что это значит? ОС: Windows 2000 SP4 КП CSP: 2.0.2049 | ||||
Ответы: | ||||
| ||||
Дело в том, что сессионный ключ экспортируется на ключе парной связи, полученном по алгоритму Диффи-Хеллмана из собственного закрытого ключа и открытого ключа получателя. Пример см. http://www.cryptopro.ru/CryptoPro/forum/myforum.asp?q=4 | ||||