Крипто-Про CSP |
//-------------------------------------------------------------------- // В данном примере осуществляется экспортирование сессионного ключа // при помощи сертификатов получателя и отправителя. // Для корректной работы этой программы необходимо создать два // сертификата и добавить их в хранилище сертификатов MY: получателя // (с именем, содержащим "Responder") и отправителя (c именем, содержащим // "Sender"). //-------------------------------------------------------------------- void HandleError(char *s); int main(void) { //-------------------------------------------------------------------- // Объявление и инициализация переменных. HCERTSTORE hStoreHandle; // Дескриптор хранилища сертификатов PCCERT_CONTEXT pCertSender; // Контекст сертификата отправителя PCCERT_CONTEXT pCertResponder; // Контекст сертификата получателя HCRYPTPROV hProvResponder; // Дескриптор CSP получателя HCRYPTPROV hProvSender; // Дескриптор CSP отправителя HCRYPTKEY hSenderKey; // Дескриптор открытого ключа отправителя HCRYPTKEY hResponderKey; // Дескриптор открытого ключа получателя HCRYPTKEY hSessionKey; // Дескриптор сессионного ключа HCRYPTKEY hAgreeKey; // Дескриптор ключа согласования BYTE *pbKeyBlobSimple; // Указатель на сессионный ключевой BLOB DWORD dwBlobLenSimple; // Длина сессионного ключевого BLOBа BYTE *pbKeyBlobSender; // Указатель на ключевой BLOB отправителя DWORD dwBlobLenSender; // Длина ключевого BLOBа отправителя BYTE *pbKeyBlobResponder; // Указатель на ключевой BLOB получателя DWORD dwBlobLenResponder; // Длина ключевого BLOBа получателя DWORD dwKeySpecSender; DWORD dwKeySpecResponder; //-------------------------------------------------------------------- // На стороне отправителя: //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Открытие системного хранилища сертификатов. hStoreHandle = CertOpenSystemStore( 0, "MY"); if(hStoreHandle) { printf("The MY store is open. \n"); } else { HandleError( "Error getting store handle."); } //-------------------------------------------------------------------- // Получение контекста сертифика, в названии которого содержится "Sender", // находящегося в хранилище сертификатов "MY". pCertSender = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"Sender", NULL); if (pCertSender) { printf("The \" Sender \" certificate is found. \n"); } else { HandleError( "Error finding certificate."); } //-------------------------------------------------------------------- // Получение дескриптора CSP, включая доступ к связанному с ним ключевому // контейнеру для контекста сертификата pCertSender. if(CryptAcquireCertificatePrivateKey( pCertSender, 0, NULL, &hProvSender, &dwKeySpecSender, NULL)) { printf("The CSP handle has been acquired. \n"); } else { HandleError("Error during CryptAcquireCertificatePrivateKey."); } //-------------------------------------------------------------------- // Поиск сертифика, в названии которого содержится "Responder", // находящегося в хранилище сертификатов "MY". pCertResponder = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"Responder", NULL); if (pCertResponder) { printf("The \" Responder \" certificate is found. \n"); } else { HandleError( "Error finding certificate."); } //-------------------------------------------------------------------- // Получение дескриптора открытого ключа получателя. if(CryptImportPublicKeyInfoEx( hProvSender, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertResponder->pCertInfo->SubjectPublicKeyInfo), 0, 0, NULL, &hResponderKey)) { printf("The responder public key has been acquired. \n"); } else { printf("Error during CryptImportPublicKeyInfoEx public key."); } //-------------------------------------------------------------------- // Определение размера BLOBа открытого ключа и распределение памяти. if(CryptExportKey( hResponderKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLenResponder)) { printf("Size of the BLOB for the responder public key determined. \n"); } else { HandleError("Error computing BLOB length."); } pbKeyBlobResponder = (BYTE*)malloc(dwBlobLenResponder); if(pbKeyBlobResponder) { printf("Memory has been allocated for the BLOB. \n"); } else { HandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Экспортирование открытого ключа получателя в BLOB открытого ключа. if(CryptExportKey( hResponderKey, 0, PUBLICKEYBLOB, 0, pbKeyBlobResponder, &dwBlobLenResponder)) { printf("Contents have been written to the BLOB. \n"); } else { HandleError("Error during CryptExportKey."); } //-------------------------------------------------------------------- // Получение дескриптора закрытого ключа отправителя. if(CryptGetUserKey( hProvSender, dwKeySpecSender, &hSenderKey)) { printf("The sender private key has been acquired. \n"); } else { printf("Error during CryptGetUserKey private key."); } //-------------------------------------------------------------------- // Получение ключа согласования импортом открытого ключа получателя из BLOBа // на закрытом ключе отправителя. if (CryptImportKey( hProvSender, pbKeyBlobResponder, dwBlobLenResponder, hSenderKey, 0, &hAgreeKey)) { printf("The responder public key has been imported. \n"); } else { printf("Error during CryptImportKey public key."); } //-------------------------------------------------------------------- // Генерация сессионного ключа. if (CryptGenKey( hProvSender, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey)) { printf("Original session key is created. \n"); } else { HandleError("ERROR -- CryptGenKey."); } //-------------------------------------------------------------------- // pbKeyBlobSimple - зашифрованный сессионный ключ, передаем его получателю // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Определение размера BLOBа сессионного ключа и распределение памяти. if(CryptExportKey( hSessionKey, hAgreeKey, SIMPLEBLOB, 0, NULL, &dwBlobLenSimple)) { printf("Size of the BLOB for the sender session key determined. \n"); } else { HandleError("Error computing BLOB length."); } pbKeyBlobSimple = (BYTE*)malloc(dwBlobLenSimple); if(pbKeyBlobSimple) { printf("Memory has been allocated for the BLOB. \n"); } else { HandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Шифрование сессионного ключа на ключе Agree. if(CryptExportKey( hSessionKey, hAgreeKey, SIMPLEBLOB, 0, pbKeyBlobSimple, &dwBlobLenSimple)) { printf("Contents have been written to the BLOB. \n"); } else { HandleError("Error during CryptExportKey."); } //-------------------------------------------------------------------- // Закрытие системного хранилища сертификатов. if(CertCloseStore( hStoreHandle, 0)) { printf("The MY store is closed. \n"); } else { HandleError( "Error closing store handle."); } //-------------------------------------------------------------------- // Уничтожение сессионного ключа. if(hSessionKey) CryptDestroyKey(hSessionKey); // Уничтожение ключа согласования. if(hAgreeKey) CryptDestroyKey(hAgreeKey); // Уничтожение дескриптора открытого ключа получателя. if(hResponderKey) CryptDestroyKey(hResponderKey); // Уничтожение дескриптора закрытого ключа отправителя. if(hSenderKey) CryptDestroyKey(hSenderKey); // Освобождение дескриптора провайдера. if(hProvSender) CryptReleaseContext(hProvSender, 0); // Освобождение контекста сертификата. if(pCertSender) CertFreeCertificateContext(pCertSender); if(pCertResponder) CertFreeCertificateContext(pCertResponder); // Освобождение памяти, используемой ключевым BLOBом. free(pbKeyBlobResponder); //-------------------------------------------------------------------- // На стороне получателя: получили зашифрованный сессионный ключ // pbKeyBlobSimple. //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Открытие системного хранилища сертификатов. hStoreHandle = CertOpenSystemStore( 0, "MY"); if(hStoreHandle) { printf("The MY store is open. \n"); } else { HandleError( "Error getting store handle."); } //-------------------------------------------------------------------- // Получение контекста сертифика, в названии которого содержится "Responder", // находящегося в хранилище сертификатов "MY". pCertResponder = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"Responder", NULL); if (pCertResponder) { printf("The \" Responder \" certificate is found. \n"); } else { HandleError( "Error finding certificate."); } //-------------------------------------------------------------------- // Получение дескриптора CSP, включая доступ к связанному с ним ключевому // контейнеру для контекста сертификата pCertResponder. if(CryptAcquireCertificatePrivateKey( pCertResponder, 0, NULL, &hProvResponder, &dwKeySpecResponder, NULL)) { printf("The CSP handle has been acquired. \n"); } else { HandleError("Error during CryptAcquireCertificatePrivateKey."); } //-------------------------------------------------------------------- // Поиск сертифика, в названии которого содержится "Sender", // находящегося в хранилище сертификатов "MY". pCertSender = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"Sender", NULL); if (pCertSender) { printf("The \" Sender \" certificate is found. \n"); } else { HandleError( "Error finding certificate."); } //-------------------------------------------------------------------- // Получение дескриптора открытого ключа отправителя. if(CryptImportPublicKeyInfoEx( hProvSender, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertSender->pCertInfo->SubjectPublicKeyInfo), 0, 0, NULL, &hSenderKey)) { printf("The sender public key has been acquired. \n"); } else { printf("Error during CryptImportPublicKeyInfoEx public key."); } //-------------------------------------------------------------------- // Определение размера BLOBа открытого ключа и распределение памяти. if(CryptExportKey( hSenderKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLenSender)) { printf("Size of the BLOB for the sender public key determined. \n"); } else { HandleError("Error computing BLOB length."); } pbKeyBlobSender = (BYTE*)malloc(dwBlobLenSender); if(pbKeyBlobSender) { printf("Memory has been allocated for the BLOB. \n"); } else { HandleError("Out of memory. \n"); } //-------------------------------------------------------------------- // Экспортирование открытого ключа отправителя в BLOB открытого ключа. if(CryptExportKey( hSenderKey, 0, PUBLICKEYBLOB, 0, pbKeyBlobSender, &dwBlobLenSender)) { printf("Contents have been written to the BLOB. \n"); } else { HandleError("Error during CryptExportKey."); } //-------------------------------------------------------------------- // Получение дескриптора закрытого ключа получателя. if(CryptGetUserKey( hProvResponder, dwKeySpecResponder, &hResponderKey)) { printf("The responder private key has been acquired. \n"); } else { printf("Error during CryptGetUserKey private key."); } //-------------------------------------------------------------------- // Получение ключа согласования импортом открытого ключа отправителя из BLOBа // на закрытом ключе получателя. if (CryptImportKey( hProvResponder, pbKeyBlobSender, dwBlobLenSender, hResponderKey, 0, &hAgreeKey)) { printf("The sender public key has been imported. \n"); } else { printf("Error during CryptImportKey public key."); } // Получение сессионного ключа импортом зашифрованного сессионного ключа // на ключе Agree. if (CryptImportKey( hProvResponder, pbKeyBlobSimple, dwBlobLenSimple, hAgreeKey, 0, &hSessionKey)) { printf("The session key has been imported. \n"); } else { printf("Error during CryptImportKey session key."); } //-------------------------------------------------------------------- // Закрытие системного хранилища сертификатов. if(CertCloseStore( hStoreHandle, 0)) { printf("The MY store is closed. \n"); } else { HandleError( "Error closing store handle."); } //-------------------------------------------------------------------- // Освобождение памяти, используемой ключевыми BLOBами. free(pbKeyBlobSimple); free(pbKeyBlobSender); // Уничтожение дескриптора закрытого ключа получателя. if(hResponderKey) CryptDestroyKey(hResponderKey); // Уничтожение дескриптора открытого ключа отправителя. if(hSenderKey) CryptDestroyKey(hSenderKey); // Уничтожение сессионного ключа. if(hSessionKey) CryptDestroyKey(hSessionKey); // Уничтожение ключа согласования. if(hAgreeKey) CryptDestroyKey(hAgreeKey); // Освобождение дескриптора провайдера. if(hProvResponder) CryptReleaseContext(hProvResponder, 0); // Освобождение контекста сертификата. if(pCertSender) CertFreeCertificateContext(pCertSender); if(pCertResponder) CertFreeCertificateContext(pCertResponder); printf("The program ran to completion without error. \n"); return 0; }// Конец main
Windows 2000/XP/2003: Необходимо Windows 2000 SP4 или
старше с Internet Explorer 6.0 или старше.
Windows NT/95/98/ME: CSP 3.0 не поддерживает (см. КриптоПро CSP
2.0 ).
Solaris: 9 Update 4 или выше.
FreeBSD: FreeBSD 5.2 или выше
Linux: RedHat 7.3, RedHad 9.0.
Ядро Windows NT: не поддерживает.
Что Вы
думаете по поводу данной статьи? |
Закажите CD c Крипто-Про CSP |