Статус: Активный участник
Группы: Участники
Зарегистрирован: 21.12.2011(UTC) Сообщений: 45 Откуда: Москва
|
Здравтствуйте!!!! Может подскажите? Как сделать эту "параллельную подпись" с помощью CryptoApi? Большое Пожалуйста!!!!! Нужно хотя бы "Эскизное" описание алгоритма. Задача уже существующую (присоединенную/отсоединенную) подпись дополнить подписью еще одного лица. Обычную подпись делаю с помощью кода: Код:
/ Создает отдельную от сообщения ЭЦП.
bool CreateSignature_int(PCCERT_CONTEXT a_pCertContext, BYTE* pbContent, CRYPT_DATA_BLOB *pSignatureBlob)
{
//const BYTE* pbContent = (BYTE*)"Test Message.";
DWORD cbContent; // Size of message
HCRYPTPROV hCryptProv; // CSP handle
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
DWORD cbEncodedBlob;
BYTE* pbEncodedBlob;
HCRYPTMSG hMsg;
DWORD dwKeySpec;
//CRYPT_VERIFY_MESSAGE_PARA msgPara;
//---------------------------------------------------------------
// Initialize cbContent to the length of pbContent
// including the terminating NULL character.
cbContent = strlen((char *) pbContent)+1;
//---------------------------------------------------------------
// Get a handle to a cryptographic provider.
if( !(CryptAcquireCertificatePrivateKey(
a_pCertContext,
0,
NULL,
&hCryptProv,
&dwKeySpec,
NULL)))
{
MyHandleError(_T("CryptAcquireContext failed"));
return FALSE;
}
memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = a_pCertContext->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = dwKeySpec;
SignerEncodeInfo.HashAlgorithm.pszObjId = m_HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;
//---------------------------------------------------------------
// Initialize the first element of an array of signers.
// Note: Currently, there is only one signer.
SignerEncodeInfoArray[0] = SignerEncodeInfo;
//---------------------------------------------------------------
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.
SignerCertBlob.cbData = a_pCertContext->cbCertEncoded;
SignerCertBlob.pbData = a_pCertContext->pbCertEncoded;
//---------------------------------------------------------------
// Initialize the first element of an array of signer BLOBs.
// Note: In this program, only one signer BLOB is used.
SignerCertBlobArray[0] = SignerCertBlob;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
//---------------------------------------------------------------
// Get the size of the encoded message BLOB.
if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
m_Encoding_Type, // Message encoding type
0, // Flags
CMSG_SIGNED, // Message type
&SignedMsgEncodeInfo, // Pointer to structure
NULL, // Inner content OID
cbContent))) // Size of content
{
MyHandleError(_T("Getting cbEncodedBlob length failed."));
return FALSE;
}
//---------------------------------------------------------------
// Allocate memory for the encoded BLOB.
if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
{
MyHandleError(_T("Malloc operation failed."));
exit_CreateSign(NULL, hCryptProv, pbEncodedBlob);
return FALSE;
}
//---------------------------------------------------------------
// Open a message to encode.
if(!(hMsg = CryptMsgOpenToEncode(
m_Encoding_Type, // Encoding type
CMSG_DETACHED_FLAG, // Flags
CMSG_SIGNED, // Message type
&SignedMsgEncodeInfo, // Pointer to structure
NULL, // Inner content OID
NULL))) // Stream information (not used)
{
MyHandleError(_T("OpenToEncode failed"));
exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
return FALSE;
}
//---------------------------------------------------------------
// Update the message with the data.
if(!(CryptMsgUpdate(
hMsg, // Handle to the message
pbContent, // Pointer to the content
cbContent, // Size of the content
TRUE))) // Last call
{
MyHandleError(_T("MsgUpdate failed"));
exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
return FALSE;
}
//---------------------------------------------------------------
// Get the resulting message.
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
pbEncodedBlob, // Pointer to the BLOB
&cbEncodedBlob)) // Size of the BLOB
{
MyHandleError(_T("MsgGetParam failed."));
exit_CreateSign(hMsg, hCryptProv, pbEncodedBlob);
return FALSE;
}
pSignatureBlob->cbData = cbEncodedBlob;
pSignatureBlob->pbData = pbEncodedBlob;
//---------------------------------------------------------------
// The message is signed and encoded.
// Close the message handle and the certificate store.
CryptMsgClose(hMsg);
CryptReleaseContext(hCryptProv, 0);
return TRUE;
}
Присоединную подпись делаю с помощью функции: Код:
bool SignMessage( PCCERT_CONTEXT *a_pCertContext, CRYPT_DATA_BLOB *pSignedMessageBlob, LPSTR sMsg )
{
bool fReturn = false;
BYTE* pbMessage;
DWORD cbMessage;
HCERTSTORE hCertStore = NULL;
//PCCERT_CONTEXT pSignerCert;
CRYPT_SIGN_MESSAGE_PARA SigParams;
DWORD cbSignedMessageBlob;
BYTE *pbSignedMessageBlob = NULL;
// Initialize the output pointer.
pSignedMessageBlob->cbData = 0;
pSignedMessageBlob->pbData = NULL;
// The message to be signed.
// Usually, the message exists somewhere and a pointer is
// passed to the application.
pbMessage =
(BYTE*) sMsg; //TEXT("The message: CryptoAPI is a good way to handle security.");
// Calculate the size of message. To include the
// terminating null character, the length is one more byte
// than the length returned by the strlen function.
cbMessage = (lstrlen((TCHAR*) pbMessage) + 1) * sizeof(TCHAR);
// Create the MessageArray and the MessageSizeArray.
const BYTE* MessageArray[] = {pbMessage};
DWORD_PTR MessageSizeArray[1];
MessageSizeArray[0] = cbMessage;
// Begin processing.
// _tprintf(TEXT("The message to be signed is \"%s\".\n"),
// pbMessage);
// Initialize the signature structure.
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = m_Encoding_Type;
SigParams.pSigningCert = *a_pCertContext;
SigParams.HashAlgorithm.pszObjId = m_HashAlgorithm;
SigParams.HashAlgorithm.Parameters.cbData = NULL;
SigParams.cMsgCert = 1;
SigParams.rgpMsgCert = a_pCertContext;
SigParams.cAuthAttr = 0;
SigParams.dwInnerContentType = 0;
SigParams.cMsgCrl = 0;
SigParams.cUnauthAttr = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.rgAuthAttr = NULL;
// First, get the size of the signed BLOB.
if(CryptSignMessage(
&SigParams,
FALSE,
1,
MessageArray,
MessageSizeArray,
NULL,
&cbSignedMessageBlob))
{
// _tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"),
// cbSignedMessageBlob);
}
else
{
MyHandleError(TEXT("Getting signed BLOB size failed"));
exit_SignMessage(pbSignedMessageBlob);
return fReturn;
}
// Allocate memory for the signed BLOB.
if(!(pbSignedMessageBlob =
(BYTE*)malloc(cbSignedMessageBlob)))
{
MyHandleError(
TEXT("Memory allocation error while signing."));
exit_SignMessage(pbSignedMessageBlob);
return fReturn;
}
// Get the signed message BLOB.
if(CryptSignMessage(
&SigParams,
FALSE,
1,
MessageArray,
MessageSizeArray,
pbSignedMessageBlob,
&cbSignedMessageBlob))
{
//_tprintf(TEXT("The message was signed successfully. \n"));
// pbSignedMessageBlob now contains the signed BLOB.
fReturn = true;
if(pbSignedMessageBlob)
{
pSignedMessageBlob->cbData = cbSignedMessageBlob;
pSignedMessageBlob->pbData = pbSignedMessageBlob;
//DWORD cbEncodedBlob = SignedMessage.cbData;
}
}
else
{
MyHandleError(TEXT("Error getting signed BLOB"));
exit_SignMessage(pbSignedMessageBlob);
return fReturn;
}
//AfxMessageBox("Подпись готова");
return fReturn;
}
Спасибо! Отредактировано пользователем 16 января 2012 г. 18:48:14(UTC)
| Причина: Не указана
|