Статус: Участник
Группы: Участники
Зарегистрирован: 27.09.2010(UTC) Сообщений: 18
|
День добрый! Код:1. Создание подписи
PCCERT_CONTEXT m_certCont;
// bsCertData - данные сертификата, dwSize - размер, szData - подписываемые данные
m_certCont = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bsCertData, dwSize);
....
CRYPT_KEY_PROV_INFO pCryptKeyProvInfo;
pCryptKeyProvInfo.pwszProvName = "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider";
pCryptKeyProvInfo.pwszContainerName = bsContName;
pCryptKeyProvInfo.dwProvType = 75;
pCryptKeyProvInfo.dwFlags = 0;
pCryptKeyProvInfo.cProvParam = 0;
pCryptKeyProvInfo.rgProvParam = NULL;
pCryptKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
BOOL ret = CertSetCertificateContextProperty(m_cert.getContext(), CERT_KEY_PROV_INFO_PROP_ID, 0, &pCryptKeyProvInfo);
.....
// szData - gjlgbcsdftvst lfyyst
BYTE* pbMessage = (BYTE*)szData;
DWORD cbMessage = (DWORD)strlen((char*) pbMessage)+1;
//--------------------------------------------------------------------
// Определение размера подписи и распределение памяти.
// Создаем и заполняем структуру для создания цифроовой подписи
CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
SigParams.pSigningCert = m_certCont;
SigParams.HashAlgorithm.pszObjId = szOID_CP_GOST_R3411;
SigParams.HashAlgorithm.Parameters.cbData = NULL;
SigParams.cMsgCert = 0;
SigParams.rgpMsgCert = NULL;
SigParams.cAuthAttr = 0;
SigParams.dwInnerContentType = 0;
SigParams.cMsgCrl = 0;
SigParams.cUnauthAttr = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.rgAuthAttr = NULL;
const BYTE* MessageArray[] = {pbMessage};
DWORD MessageSizeArray[1];
MessageSizeArray[0] = cbMessage;
if(CryptSignMessage(
&SigParams, // указатель на SigParams
TRUE, // подпись создается отдельно
1, // число сообщений
MessageArray, // сообщение
MessageSizeArray, // длина сообщения
NULL, // буфер для подписи
&cbSignedMessageBlob)){ // размер буфера
// выделяем память под подпись
if(!(pbSignedMessageBlob = new BYTE[cbSignedMessageBlob])){
throw CCryptoError("Ошибка выделения памяти под подпись",GetLastError());
}
// формируем подпись
if(!CryptSignMessage(
&SigParams, // указатель на SigParams
TRUE, // подпись создается отдельно
1, // число сообщений
MessageArray, // сообщение
MessageSizeArray, // длина сообщения
pbSignedMessageBlob, // буфер для подписи
&cbSignedMessageBlob)) // размер буфера
{
throw CCryptoError("Ошибка формирования подписи",GetLastError());
}
2. Верификация
PCCERT_CONTEXT m_certCont;
// bsCertData - данные сертификата, dwSize - размер, szData - проверяемые данные
m_certCont = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bsCertData, dwSize);
....
CRYPT_KEY_PROV_INFO pCryptKeyProvInfo;
pCryptKeyProvInfo.pwszProvName = "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider";
pCryptKeyProvInfo.pwszContainerName = bsContName;
pCryptKeyProvInfo.dwProvType = 75;
pCryptKeyProvInfo.dwFlags = 0;
pCryptKeyProvInfo.cProvParam = 0;
pCryptKeyProvInfo.rgProvParam = NULL;
pCryptKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
BOOL ret = CertSetCertificateContextProperty(m_cert.getContext(), CERT_KEY_PROV_INFO_PROP_ID, 0, &pCryptKeyProvInfo
...
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
// Заполнение структуры для верификации
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = MyGetSignerCertificateCallback;
VerifyParams.pvGetArg = (void*)m_certCont;
BYTE* pbMessage = (BYTE*)szData;
DWORD cbMessage = (DWORD)strlen((char*) pbMessage)+1;
const BYTE* MessageArray[] = {pbMessage};
DWORD MessageSizeArray[1];
MessageSizeArray[0] = cbMessage;
// верификация подписи
if(!CryptVerifyDetachedMessageSignature(
&VerifyParams, // указатель на структуру VerifyParams
0, //
pbSignature, // указатель на подпись
dwSignLen, // длина подписи
1, // число сообщений
MessageArray, // сообщение
MessageSizeArray, // длина сообщения
&m_certCont)){ // указатель на сертификат
throw CCryptoError("Ошибка проверки подписи",GetLastError());
}
}
|