Національний авіаційний університет Навчально-науковий інститут Комп’ютерних інформаційних технологій Кафедра комп’ютеризованих систем захисту інформації Звіт з лабораторної роботи №8 з дисципліни «Прикладна криптологія» Використання криптографічного інтерфейсу Windows при розробці додатків. Шифрування і дешифрування даних. Формування і перевірка ЕЦП. Керування доступом до контейнера ключів. Виконав: студент групи БІ-443 Мусель А.О. Викладач: Єгоров С. В. «___» __________ 2018 р. _______________ (підпис викладача) Київ 2018 Лабораторна робота № 8 Тема: Використання криптографічного інтерфейсу Windows при розробці додатків. Шифрування і дешифрування даних. Формування і перевірка ЕЦП. Керування доступом до контейнера ключів. Мета: На практиці засвоїти принципи організації програм, що забезпечують шифрування і дешифрування даних, отримання і перевірку ЕЦП, формування дайджесту повідомлень. Засвоїти принципи використання функцій, що забезпечують керування доступом до контейнеру ключів. Завдання: Ознайомитися з теоретичними положеннями, присвяченими принципам роботи з криптографічним інтерфейсом Windows. Написати програму що реалізує: шифрування вмісту файлу «init.txt»; дешифрування отриманого криптотексту; підпис текстового файлу та його верифікацію. Хід роботи: crypted is the message to be // encrypted and signed. const BYTE *pbToBeSignedAndEncrypted = (const unsigned char *)"Insert the message to be signed " "here"; DWORD cbToBeSignedAndEncrypted = lstrlenA((const char *)pbToBeSignedAndEncrypted) + 1; BYTE *pbSignedAndEncryptedBlob; DWORD cbSignedAndEncryptedBlob; BYTE *pReturnMessage; pbSignedAndEncryptedBlob = SignAndEncrypt( pbToBeSignedAndEncrypted, cbToBeSignedAndEncrypted, &cbSignedAndEncryptedBlob); printf(("The following is the signed and encrypted ") TEXT("message.\n")); ShowBytes(pbSignedAndEncryptedBlob,cbSignedAndEncryptedBlob/4); WriteSignedAndEncryptedBlob( cbSignedAndEncryptedBlob, pbSignedAndEncryptedBlob); if(pReturnMessage = DecryptAndVerify( pbSignedAndEncryptedBlob, cbSignedAndEncryptedBlob)) { printf((" The returned, verified message is ->\n%s\n"), pReturnMessage); printf((" The program executed without error.\n")); } else { printf(("Verification failed.\n")); } } // End Main. BYTE* SignAndEncrypt( const BYTE *pbToBeSignedAndEncrypted, DWORD cbToBeSignedAndEncrypted, DWORD *pcbSignedAndEncryptedBlob) { //--------------------------------------------------------------- // Declare and initialize local variables. FILE *hToSave; HCERTSTORE hCertStore; PCCERT_CONTEXT pReceiverCertContext; TCHAR pszNameString[256]; CRYPT_SIGN_MESSAGE_PARA SignPara; CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara; DWORD cRecipientCert; PCCERT_CONTEXT rgpRecipientCert[5]; BYTE *pbSignedAndEncryptedBlob = NULL; CERT_NAME_BLOB Subject_Blob; BYTE *pbDataIn; DWORD dwKeySpec; HCRYPTPROV hCryptProv; if ( !( hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"my"))) { MyHandleError(TEXT("The MY store could not be opened.")); } if(!(pSignerCertContext = CertFindCertificateInStore( hCertStore, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_STR, SIGNER_NAME, NULL))) { MyHandleError(TEXT("Cert not found.\n")); } if(CertGetNameString( pSignerCertContext , CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { _tprintf( TEXT("The SIMPLE_DISPLAY_TYPE message signer's name is ") TEXT("%s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the signer failed.\n")); } if(CertGetNameString( pSignerCertContext, CERT_NAME_RDN_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { _tprintf( TEXT("The RDM_TYPE message signer's name is %s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the signer failed.\n")); } if(!( CryptAcquireCertificatePrivateKey( pSignerCertContext, 0, NULL, &hCryptProv, &dwKeySpec, NULL))) { MyHandleError(TEXT("CryptAcquireCertificatePrivateKey.\n")); } if( !(hToSave= fopen("s.txt","rb"))) { MyHandleError(TEXT("Source file was not opened.\n")); } fread( &(Subject_Blob.cbData), sizeof(DWORD), 1, hToSave); if(ferror(hToSave)) { MyHandleError(TEXT("The size of the BLOB was not read.\n")); } if(!(pbDataIn = (BYTE *) malloc(Subject_Blob.cbData))) { MyHandleError(TEXT("Memory allocation error.")); } fread( pbDataIn, Subject_Blob.cbData, 1, hToSave); if(ferror(hToSave)) { MyHandleError(TEXT("BLOB not read.")); } fclose(hToSave); Subject_Blob.pbData = pbDataIn; if(!(pReceiverCertContext = CertFindCertificateInStore( hCertStore, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_NAME, &Subject_Blob, NULL))) { MyHandleError(TEXT("Receiver certificate not found.")); } if(CertGetNameString( pReceiverCertContext , CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { printf(("The message receiver is %s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the receiver failed.\n")); } SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); SignPara.dwMsgEncodingType = MY_ENCODING_TYPE; SignPara.pSigningCert = pSignerCertContext ; SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2; SignPara.HashAlgorithm.Parameters.cbData = 0; SignPara.pvHashAuxInfo = NULL; SignPara.cMsgCert = 1; SignPara.rgpMsgCert = &pSignerCertContext ; SignPara.cMsgCrl = 0; SignPara.rgpMsgCrl = NULL; SignPara.cAuthAttr = 0; SignPara.rgAuthAttr = NULL; SignPara.cUnauthAttr = 0; SignPara.rgUnauthAttr = NULL; SignPara.dwFlags = 0; SignPara.dwInnerContentType = 0; EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA); EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE; EncryptPara.hCryptProv = 0; EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4; EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0; EncryptPara.pvEncryptionAuxInfo = NULL; EncryptPara.dwFlags = 0; EncryptPara.dwInnerContentType = 0; cRecipientCert = 1; rgpRecipientCert[0] = pReceiverCertContext; *pcbSignedAndEncryptedBlob = 0; pbSignedAndEncryptedBlob = NULL; if( CryptSignAndEncryptMessage( &SignPara, &EncryptPara, cRecipientCert, rgpRecipientCert, pbToBeSignedAndEncrypted, cbToBeSignedAndEncrypted, NULL, // the pbSignedAndEncryptedBlob pcbSignedAndEncryptedBlob)) { printf(("%d bytes for the buffer .\n"), *pcbSignedAndEncryptedBlob); } else { MyHandleError(TEXT("Getting the buffer length failed.")); } if(!(pbSignedAndEncryptedBlob = (unsigned char *)malloc(*pcbSignedAndEncryptedBlob))) { MyHandleError(TEXT("Memory allocation failed.")); } if( CryptSignAndEncryptMessage( &SignPara, &EncryptPara, cRecipientCert, rgpRecipientCert, pbToBeSignedAndEncrypted, cbToBeSignedAndEncrypted, pbSignedAndEncryptedBlob, pcbSignedAndEncryptedBlob)) { printf(("The message is signed and encrypted.\n")); } else { MyHandleError( TEXT("The message failed to sign and encrypt.")); } if(pSignerCertContext ) { CertFreeCertificateContext(pSignerCertContext); } if(pReceiverCertContext ) { CertFreeCertificateContext(pReceiverCertContext); } CertCloseStore(hCertStore, 0); return pbSignedAndEncryptedBlob; } // End SignAndEncrypt. BYTE* DecryptAndVerify( BYTE *pbSignedAndEncryptedBlob, DWORD cbSignedAndEncryptedBlob) { HCERTSTORE hCertStore; CRYPT_DECRYPT_MESSAGE_PARA DecryptPara; CRYPT_VERIFY_MESSAGE_PARA VerifyPara; DWORD dwSignerIndex = 0; BYTE *pbDecrypted; DWORD cbDecrypted; if ( !( hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"my"))) { MyHandleError(TEXT("The MY store could not be opened.")); } DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA); DecryptPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE; DecryptPara.cCertStore = 1; DecryptPara.rghCertStore = &hCertStore; VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA); VerifyPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE; VerifyPara.hCryptProv = 0; VerifyPara.pfnGetSignerCertificate = NULL; VerifyPara.pvGetArg = NULL; pbDecrypted = NULL; cbDecrypted = 0; if(!(CryptDecryptAndVerifyMessageSignature( &DecryptPara, &VerifyPara, dwSignerIndex, pbSignedAndEncryptedBlob, cbSignedAndEncryptedBlob, NULL, // pbDecrypted &cbDecrypted, NULL, NULL))) { MyHandleError(TEXT("Failed getting size.")); } if(!(pbDecrypted = (BYTE *)malloc(cbDecrypted))) { MyHandleError(TEXT("Memory allocation failed.")); } if(!(CryptDecryptAndVerifyMessageSignature( &DecryptPara, &VerifyPara, dwSignerIndex, pbSignedAndEncryptedBlob, cbSignedAndEncryptedBlob, pbDecrypted, &cbDecrypted, NULL, NULL))) { pbDecrypted = NULL; } CertCloseStore( hCertStore, 0); //--------------------------------------------------------------- // Return the decrypted string or NULL. return pbDecrypted; } // End of DecryptandVerify. void WriteSignedAndEncryptedBlob( DWORD cbBlob, BYTE *pbBlob) { // with the public key from the certificate used when // the message was encrypted. FILE *hOutputFile; if( !(hOutputFile = _tfopen(TEXT("sandvout.txt"), TEXT("wb")))) { MyHandleError(TEXT("Output file was not opened.\n")); } fwrite( &cbBlob, sizeof(DWORD), 1, hOutputFile); if(ferror(hOutputFile)) { MyHandleError( TEXT("The size of the BLOB was not written.\n")); } fwrite( pbBlob, cbBlob, 1, hOutputFile); if(ferror(hOutputFile)) { MyHandleError( TEXT("The bytes of the BLOB were not written.\n")); } else { printf(("The BLOB has been written to the file.\n")); } fclose(hOutputFile); } // End of WriteSignedAndEcryptedBlob. void ShowBytes(BYTE *s, DWORD len) { DWORD TotalChars = 0; DWORD ThisLine = 0; while(TotalChars < len) { if(ThisLine > 70) { ThisLine = 0; printf(("\n")); } if( s[TotalChars] < '0' || s[TotalChars] > 'z') { printf(("-")); } else { printf(("%c"), s[TotalChars]); } TotalChars++; ThisLine++; } printf(("\n")); } // End of ShowBytes. |