Рутокен ЭЦП, расшифровка сообщения.
Добрый день. Пытаюсь разобраться со следующей проблемой.
Есть сообщение, которое было зашифрованно через CryptEncryptMessage(...) следующим образом
DWORD CProviderCSP::Encrypt(const BYTE* pbtData, UINT nSize, const CERT_CONTEXT* pRecipientCert,BYTE*& pdtEncrypted, DWORD& dwEncryptedSize)
{
ASSERT(m_pcryptoAPI!=NULL);
//заполняем параметры
CRYPT_ENCRYPT_MESSAGE_PARA pMsgParam;
pMsgParam.cbSize=sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
memset(&pMsgParam, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
pMsgParam.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
pMsgParam.dwMsgEncodingType = PKCS_7_ASN_ENCODING|X509_ASN_ENCODING;
pMsgParam.hCryptProv = NULL;
pMsgParam.ContentEncryptionAlgorithm.pszObjId = "1.2.643.2.2.21"; //szOID_CP_GOST_28147
const CERT_CONTEXT* pCert[1];
pCert[0]=pRecipientCert;
pdtEncrypted=NULL;
DWORD dwErr=ERROR_SUCCESS;
BOOL bRes=CryptEncryptMessage(&pMsgParam,1,pCert,pbtData,nSize,NULL,&dwEncryptedSize);
if(bRes)
{
pdtEncrypted=new BYTE[dwEncryptedSize];
if(pdtEncrypted==NULL)
dwErr=E_OUTOFMEMORY;
}
else
dwErr=GetLastError();
if(dwErr==ERROR_SUCCESS)
{
if(!CryptEncryptMessage(&pMsgParam,1,pCert,pbtData,nSize,pdtEncrypted,&dwEncryptedSize))
{
dwErr=GetLastError();
delete [] pdtEncrypted;
pdtEncrypted=NULL;
}
}
return dwErr;
}
Необходимо расшифровать его при помощи PKCS#11 библиотеки. Пытаюсь сделать так:
....
//Инициализация библиотеки, С_Logon -ОК
....
CK_OBJECT_CLASS lPrivateKeyClass = CKO_SECRET_KEY;
CK_KEY_TYPE lKeyType = CKK_GOST28147;
CK_BBOOL bDesrypt=CK_TRUE;
CK_ATTRIBUTE stAttrFind[] =
{
{ CKA_DECRYPT, &bDesrypt, sizeof( CK_BBOOL ) },
//{ CKA_KEY_TYPE, &lKeyType, sizeof( lKeyType ) },
//Если раскомментировать строку то C_FindObjects вернет 0 найденных объектов
{ CKA_ID, ( CK_CHAR* )(( const char* )astrID ), ( CK_ULONG )astrID.GetLength() },
};
lRetCode = pstFL->C_FindObjectsInit( m_hSession, &stAttrFind[0], sizeof( stAttrFind ) / sizeof( stAttrFind[0] ) );
ASSERT( lRetCode == CKR_OK );
unsigned long lCount;
CK_OBJECT_HANDLE hObject;
lRetCode = pstFL->C_FindObjects(m_hSession, &hObject, 1, &lCount );
pstFL->C_FindObjectsFinal( m_hSession );
if( lRetCode == CKR_OK && lCount == 0 )
lRetCode = 0x0000FFFD; // Ключевой объект не найден
if( lRetCode == CKR_OK )
{
ASSERT( hObject != ( CK_OBJECT_HANDLE )NULL );
CK_MECHANISM stMechanizm;
CK_BYTE encIV[8];
CK_ULONG encIVLength = sizeof(encIV);
stMechanizm.mechanism=CKM_GOSTR3410;
//stMechanizm.mechanism=CKM_GOST28147;
//Если подставить механизм CKM_GOST28147 то C_DecryptInit
//возвращает 0x00000063 CKR_KEY_TYPE_INCONSISTENT
stMechanizm.pParameter=NULL;
stMechanizm.ulParameterLen=0;
lRetCode = pstFL->C_DecryptInit(m_hSession, &stMechanizm, hObject );
if( lRetCode == CKR_OK )
{
lRetCode=pstFL->C_Decrypt(m_hSession, (CK_BYTE_PTR)pbtData, nSize, pbtDecrypted, &dwDecryptedSize);
if(lRetCode == CKR_OK)
{
pbtDecrypted=new BYTE[dwDecryptedSize];
memset(pbtDecrypted,0,dwDecryptedSize);
//Тут получаю код ошибки 0x00000041 CKR_ENCRYPTED_DATA_LEN_RANGE
lRetCode=pstFL->C_Decrypt(m_hSession, (CK_BYTE_PTR)pbtData, nSize, (CK_BYTE_PTR)pbtDecrypted, &dwDecryptedSize);
}
}
}
Я сильно подозреваю что проблема в моем недопонимании. Видимо зашифрованное сообщение содержит что то еще помимо непосредственно данных. Но вопрос тогда, как мне выдернуть из него сами данные, которые я должен передать на вход функции C_Decrypt
Заранее спасибо за ответ.
P.S.
Когда сообщение шифруется в качестве сертификата получателя передается сертификат, который установлен на токене.