Крипто-Про CSP |
//-------------------------------------------------------------------- // Пример кода для зашифрования данных и создания зашифрованного // сообщения при помощи функции CryptEncryptMessage. // Для функционирования данного кода необходим контейнер с ключом // AT_KEYEXCHANGE с именем, совпадающим с именем текущего пользователя. // Ключ можно создать используя пример CryptAcquireContext. //-------------------------------------------------------------------- #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) void HandleError(char *s); //-------------------------------------------------------------------- // В этой программе используется функция GetRecipientCert, объявленная // здесь и описанная после main. PCCERT_CONTEXT GetRecipientCert( HCERTSTORE hCertStore); //-------------------------------------------------------------------- // В этой программе используется функция ByteToStr, объявленная здесь // и описанная после main. Код функции ByteToStr также можно найти среди // универсальных функций. void ByteToStr( DWORD cb, void* pv, LPSTR sz); //-------------------------------------------------------------------- // В этой программе используется функция DecryptMessage, объявленная // здесь и описанная после main. BOOL DecryptMessage( BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, HCERTSTORE hStoreHandle); int main() { //-------------------------------------------------------------------- // Объявление и инициализация переменных. Они получают указатель на // сообщение, которое будет зашифровано. В данном коде создается сообщение, // получается указатель на него. В действительности, обычно содержимое // сообщения уже где-то существует и указатель на сообщение устанавливается // приложением. BYTE* pbContent = (BYTE*) "Security is our business."; // Сообщение DWORD cbContent = (DWORD)(strlen((char *)pbContent)+1); // Длина сообщения HCRYPTPROV hCryptProv; // дескриптор CSP HCERTSTORE hStoreHandle; PCCERT_CONTEXT pRecipientCert; PCCERT_CONTEXT RecipientCertArray[1]; DWORD EncryptAlgSize; CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm; CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams; DWORD EncryptParamsSize; BYTE* pbEncryptedBlob; DWORD cbEncryptedBlob; //-------------------------------------------------------------------- // Начало обработки данных. printf("About to begin with the message %s.\n",pbContent); printf("The message length is %d bytes. \n", cbContent); //-------------------------------------------------------------------- // Получение дескриптора криптографического провайдера. if(CryptAcquireContext( &hCryptProv, // Адрес возврашаемого дескриптора. NULL, // Используется имя текущего // зарегестрированного пользователя. NULL, // Используется провайдер по умолчанию. 75, // Необходимо для зашифрования и подписи. 0)) // Никакие флаги не нужны. { printf("A CSP has been acquired. \n"); } else { HandleError("Cryptographic context could not be acquired."); } //-------------------------------------------------------------------- // Открытие системного хранилища сертификатов. hStoreHandle = CertOpenSystemStore( hCryptProv, "MY"); if(hStoreHandle) { printf("The MY store is open. \n"); } else { HandleError( "Error getting store handle."); } //-------------------------------------------------------------------- // Получение указателя на сертификат издателя с помощью // функции GetRecipientCert. pRecipientCert = GetRecipientCert( hStoreHandle); if(pRecipientCert) { printf("A recipient's certificate has been acquired. \n"); } else { printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n"); printf("property and an AT_KEYEXCHANGE private key available. \n"); printf("While the message could be encrypted, in this case, \n"); printf("it could not be decrypted in this program. \n"); printf("For more information, see the documentation for \n"); printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n"); HandleError( "No Certificate with AT_KEYEXCHANGE key in store."); } //-------------------------------------------------------------------- // Создание RecipientCertArray. RecipientCertArray[0] = pRecipientCert; //-------------------------------------------------------------------- // Инициализация структуры идентификатора алгоритма. EncryptAlgSize = sizeof(EncryptAlgorithm); //-------------------------------------------------------------------- // Инициализация структуры с нулем. memset(&EncryptAlgorithm, 0, EncryptAlgSize); //-------------------------------------------------------------------- // Установка необходимого элемента. EncryptAlgorithm.pszObjId = OID_CipherVar_Default; //-------------------------------------------------------------------- // Инициализация структуры CRYPT_ENCRYPT_MESSAGE_PARA. EncryptParamsSize = sizeof(EncryptParams); memset(&EncryptParams, 0, EncryptParamsSize); EncryptParams.cbSize = EncryptParamsSize; EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE; EncryptParams.hCryptProv = hCryptProv; EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm; //-------------------------------------------------------------------- // Вызов функции CryptEncryptMessage. if(CryptEncryptMessage( &EncryptParams, 1, RecipientCertArray, pbContent, cbContent, NULL, &cbEncryptedBlob)) { printf("The encrypted message is %d bytes. \n",cbEncryptedBlob); } else { HandleError( "Getting EncrypBlob size failed."); } //-------------------------------------------------------------------- // Распределение памяти под возвращаемый BLOB. pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob); if(pbEncryptedBlob) { printf("Memory has been allocated for the encrypted BLOB. \n"); } else { HandleError("Memory allocation error while encrypting."); } //-------------------------------------------------------------------- // Повторный вызов функции CryptEncryptMessage для зашифрования содержимого. if(CryptEncryptMessage( &EncryptParams, 1, RecipientCertArray, pbContent, cbContent, pbEncryptedBlob, &cbEncryptedBlob)) { printf( "Encryption succeeded. \n"); } else { HandleError("Encryption failed."); } //-------------------------------------------------------------------- // Вызов функции DecryptMessage, код которой описан после main, // для расшифрования сообщения. if(DecryptMessage( pbEncryptedBlob, cbEncryptedBlob, hStoreHandle)) { printf("Decryption succeeded. \n"); } else { printf("Decryption failed. \n"); } //-------------------------------------------------------------------- // Освобождение памяти. CertFreeCertificateContext(pRecipientCert); if(CertCloseStore( hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)) { printf("The MY store was closed without incident. \n"); } else { printf("Store closed after encryption -- \n" "but not all certificates or CRLs were freed. \n"); } if(hCryptProv) { CryptReleaseContext(hCryptProv,0); printf("The CSP has been released. \n"); } else { printf("CSP was NULL. \n"); } } // Конец main //-------------------------------------------------------------------- // Определение функции DecryptMessage. BOOL DecryptMessage( BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, HCERTSTORE hStoreHandle) //-------------------------------------------------------------------- // Пример функции для расшифрования зашифрованного сообщения с // использованием функции CryptDecryptMessage. ЕЕ параметрами являются // pbEncryptedBlob, зашифрованное сообщение; cbEncryptedBlob, длина // этого сообщения; и hStoreHandle, дескриптор // открытого хранилища сертификатов. { //-------------------------------------------------------------------- // Объявление и инициализация локальных переменных. DWORD cbDecryptedMessage; char* EncryptedString = new char[(cbEncryptedBlob * 2) +1]; HCERTSTORE CertStoreArray[] = {hStoreHandle}; CRYPT_DECRYPT_MESSAGE_PARA DecryptParams; DWORD DecryptParamsSize = sizeof(DecryptParams); BYTE* pbDecryptedMessage; LPSTR DecryptedString; BOOL fReturn = TRUE; //-------------------------------------------------------------------- // Получение указателя на зашифрованное сообщение, pbEncryptedBlob, // и его длину, cbEncryptedBlob. В этом примере они устанавливаются // как параметры совместно с CSP и дескриптором открытого хранилища. //-------------------------------------------------------------------- // Просмотр зашифрованного BLOBа. // Вызов функции ByteToStr для конвертирования байтового BLOBа // шестнадцатиричный формат ASCII. ByteToStr( cbEncryptedBlob, pbEncryptedBlob, EncryptedString); //-------------------------------------------------------------------- // Печать конвертированной строки. printf("The encrypted string is: \n%s\n",EncryptedString); //-------------------------------------------------------------------- // В этом примере дескриптор хранилище MY установлен как параметр. //-------------------------------------------------------------------- // Создание "CertStoreArray." // В этом примере был выполнен в процессе объявления и инициализации // локальных переменных, потому что дескриптор хранилища в функции // был установлен как параметр. //-------------------------------------------------------------------- // Инициализация структуры CRYPT_DECRYPT_MESSAGE_PARA. memset(&DecryptParams, 0, DecryptParamsSize); DecryptParams.cbSize = DecryptParamsSize; DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE; DecryptParams.cCertStore = 1; DecryptParams.rghCertStore = CertStoreArray; //-------------------------------------------------------------------- // Расшифрование сообщения. // Вызов фнукции CryptDecryptMessage для получения возвращаемого размера // данных. if(CryptDecryptMessage( &DecryptParams, pbEncryptedBlob, cbEncryptedBlob, NULL, &cbDecryptedMessage, NULL)) { printf("The size for the decrypted message is: %d.\n",cbDecryptedMessage); } else { HandleError( "Error getting decrypted message size"); } //-------------------------------------------------------------------- // Освобождение памяти под возвращаемые расшифрованные данные. pbDecryptedMessage = (BYTE*)malloc(cbDecryptedMessage); if(pbDecryptedMessage) { printf("Memory has been allocated for the decrypted message. \n"); } else { HandleError("Memory allocation error while decrypting"); } //-------------------------------------------------------------------- // Вызов функции CryptDecryptMessage для расшифрования данных. if(CryptDecryptMessage( &DecryptParams, pbEncryptedBlob, cbEncryptedBlob, pbDecryptedMessage, &cbDecryptedMessage, NULL)) { DecryptedString = (LPSTR) pbDecryptedMessage; printf("Message Decrypted Successfully. \n"); printf("The decrypted string is: %s\n",DecryptedString); } else { printf("Error decrypting the message \n"); printf("Error code %x \n",GetLastError()); fReturn = FALSE; } //-------------------------------------------------------------------- // Освобождение памяти. free(pbEncryptedBlob); free(pbDecryptedMessage); return fReturn; } // Конец определения DecryptMessage //-------------------------------------------------------------------- // Определение функции ByteToStr. void ByteToStr( DWORD cb, void* pv, LPSTR sz) //-------------------------------------------------------------------- // Устанавливаемые параметры: // pv - байтовый массив для конвертирования. // cb - число байтов в массиве. // sz - указатель на возвращаемую строку. { //-------------------------------------------------------------------- // Объявление и инициализация локальных переменных. BYTE* pb = (BYTE*) pv; // Локальный указатель на байт в байтовом массиве DWORD i; // Локальный счетчик цикла int b; // Локальная переменная //-------------------------------------------------------------------- // Начало выполнения цикла. for (i = 0; i<cb; i++) { b = (*pb & 0xF0) >> 4; *sz++ = (CHAR)((b <= 9) ? b + '0' : (b - 10) + 'A'); b = *pb & 0x0F; *sz++ = (CHAR)((b <= 9) ? b + '0' : (b - 10) + 'A'); pb++; } *sz++ = 0; } // Конец определения ByteToStr //-------------------------------------------------------------------- // В этом примере используется функция HandleError, функция обработки // простых ошибок, для печати сообщения об ошибке в стандартный файл // ошибок (stderr) и выхода из программы. // В большинстве приложений эта функция заменяется другой функцией, // которая выводит более полное сообщение об ошибке. void HandleError(char *s) { fprintf(stderr,"An error occurred in running the program. \n"); fprintf(stderr,"%s\n",s); fprintf(stderr, "Error number %x.\n", GetLastError()); fprintf(stderr, "Program terminating. \n"); exit(1); } // Конец опредления HandleError //-------------------------------------------------------------------- // GetRecipientCert перечисляет сертификаты в хранилище и находит // первый сертификат, обладающий ключем AT_EXCHANGE. Если сертификат // сертификат найден, то возвращается указатель на него. PCCERT_CONTEXT GetRecipientCert( HCERTSTORE hCertStore) //-------------------------------------------------------------------- // Устанавлеваемый параметр: // hCertStore, дескриптор хранилища, в котором будет осуществлен поиск. { //-------------------------------------------------------------------- // Объявление и инициализация локальных переменных. PCCERT_CONTEXT pCertContext = NULL; BOOL fMore = TRUE; DWORD dwSize = 0; CRYPT_KEY_PROV_INFO* pKeyInfo = NULL; DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID; //-------------------------------------------------------------------- // Поиск сертификатов в хранилище до тех пор, пока не будет достигнут // конец хранилища, или сертификат с ключем AT_KEYEXCHANGE не будет найден. pCertContext= CertFindCertificateInStore( hCertStore, // Дескриптор хранилища, в котором будет осуществлен поиск. 0, // Тип зашифрования. В этом поиске не используется. 0, // dwFindFlags. Специальный критерий поиска. // в этом поиске не используется. CERT_FIND_PROPERTY, // Тип поиска. Задает вид поиска, который будет // осуществлен. В этом случае, поиск сертификатов, // имеющих определенные расширенные свойства. &PropId, // pvFindPara. Выдает определенное значение // поиска, в данном случае идентификатор // расширенного свойства. pCertContext); // pCertContext равен NULL для первого вызова // функции. Если функция вызывается в цикле, // после первого ее вызова pCertContext становится // указателем, возвращенным предыдущим вызовом. while(fMore && pCertContext) { //------------------------------------------------------------- // Для простоты в этом коде реализован только поиск первого // вхождения ключа AT_KEYEXCHANGE. Во многих случаях, помимо // поиска типа ключа, осуществляется также поиск определенного // имени субъекта. //------------------------------------------------------------- // Однократный вызов функции CertGetCertificateContextProperty // для получения возврашенного размера структуры. if(!(CertGetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSize))) { HandleError("Error getting key property."); } //-------------------------------------------------------------- // распределение памяти под возвращенную структуру. if(pKeyInfo) free(pKeyInfo); pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize); if(!pKeyInfo) { HandleError("Error allocating memory for pKeyInfo."); } //-------------------------------------------------------------- // Получение структуры информации о ключе. if(!(CertGetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pKeyInfo, &dwSize))) { HandleError("The second call to the function failed."); } //------------------------------------------- // Проверка члена dwKeySpec на расширенный ключ. if(pKeyInfo->dwKeySpec == AT_KEYEXCHANGE) { fMore = FALSE; } } // Конец цикла while if(pKeyInfo) free(pKeyInfo); return (pCertContext); } // Конец определения GetRecipientCert
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 |