В поисках информации по вопросу я сталкивался с проблемами пользователей, по описанию которых даже я, при том что опыт программирования по части шифрования у меня неделя, понимал в чем проблема, т.к. сам сталкивался с этим.
Опираясь на это, я считаю, что по описанию проблемы можно понять в чем может быть загвоздка. В данном случае проблема такая: сообщение приходит, outlook обращается к ключевому контейнеру, ввожу ПИН, сообщение открывается, но пустое. При этом p7mviewer его открывает как надо, расшифровывает верно.
Шифрование:
BYTE* pbContent = (BYTE*) "test";
DWORD cbContent = (DWORD)(strlen((char *)pbContent));
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
CRYPT_SIGN_MESSAGE_PARA SigParams;
BYTE* pbEncryptedBlob = NULL;
DWORD cbEncryptedBlob;
if(!CryptAcquireContext( &hCryptProv, 0, NULL, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT))
{
HandleError("Cryptographic context could not be acquired.");
}
printf("CSP has been acquired. \n");
hStoreHandle = CertOpenSystemStore(hCryptProv, L"MY");
if(!hStoreHandle)
{
HandleError( "Error getting store handle.");
}
printf("The MY store is open. \n");
pRecipientCert = GetRecipientCert(hStoreHandle);
if(!pRecipientCert)
{
HandleError( "No Certificate with AT_KEYEXCHANGE key in store.");
}
GetCertDName(&pRecipientCert->pCertInfo->Subject, &szDName);
printf("A recipient's certificate has been acquired: %s\n", szDName);
memset(&EncryptAlgorithm, 0, sizeof(CRYPT_ALGORITHM_IDENTIFIER));
EncryptAlgorithm.pszObjId = szOID_CP_GOST_28147;
memset(&EncryptParams, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
EncryptParams.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;
if(!CryptEncryptMessage(&EncryptParams,1,&pRecipientCert,pbContent,cbContent,NULL,&cbEncryptedBlob))
{
HandleError( "Getting EncrypBlob size failed.");
}
printf("The encrypted message is %d bytes. \n", cbEncryptedBlob);
pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob);
if(!pbEncryptedBlob) HandleError("Memory allocation error while encrypting.");
if(!CryptEncryptMessage(&EncryptParams,1,&pRecipientCert,pbContent,cbContent,pbEncryptedBlob,&cbEncryptedBlob))
{
HandleError("Encryption failed.");
}
printf( "Encryption succeeded. \n");
После чего полученный blob записываем в файл
FILE *hOutputFile;
hOutputFile = _tfopen( outname , TEXT("wb");
fwrite( pbBlob, cbBlob, 1, hOutputFile);
fclose(hOutputFile);
Далее генерируем заголовок для письма
From: <почта> \r\n
To: <почта> \r\n
MIME-Version: 1.0 \r\n
Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\" \r\n
Content-Transfer-Encoding: base64 \r\n
Content-Disposition: attachment; filename=smime.p7m \r\n\r\n
читаем полученный на прошлом шаге файл, кодируем в base64, дописываем сюда и отправляем полученное сообщение.
Достаем из вложения smime.p7m, смотрим через p7mviewer - видит "test". Открываем в outlook'е - пусто. Только запрашивает доступ к ключевому контейнеру.