Ключевое слово в защите информации
ключевое слово
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline MipT.Shurik  
#1 Оставлено : 17 марта 2011 г. 13:31:01(UTC)
MipT.Shurik

Статус: Участник

Группы: Участники
Зарегистрирован: 15.10.2010(UTC)
Сообщений: 10
Откуда: Moscow

1) Добрый день
В программе пользуюсь функциями которые указаны в примерах для вашего csp
Шифруется-подписывается-расшифровывается-проверяется все нормально, когда посылаю с помощью этих функций сообщения оутлуку, то тоже все хорошо, оутлук все понимает. Но когда просто пытаюсь с помощью cryptcp расшифровать что-то из файла, то проблемы:

C:\TEMP\distr\cryptcp>cryptcp -decr -f ayush.cer bs bsout -nochain
CryptCP 3.33 (c) "Крипто-Про", 2002-2010.
Утилита командной строки для защиты данных.
-decr - Расшифровать данные из сообщения.

Будет использован следующий сертификат:
Субъект:ayushchenko@rapida.ru, ayushchenko, iss, rapida, Moscow, RU, RU
Действителен с 18.01.2011 15:37:14 по 04.10.2014 07:09:41

Расшифрование данных... 0%Ошибка: Некорректное преобразование BASE64. (0x20000067)
[ErrorCode: 0x20000067]

C:\TEMP\distr\cryptcp>cryptcp -decr -f ayush.cer bin bsout -nochain
CryptCP 3.33 (c) "Крипто-Про", 2002-2010.
Утилита командной строки для защиты данных.
-decr - Расшифровать данные из сообщения.

Будет использован следующий сертификат:
Субъект:ayushchenko@rapida.ru, ayushchenko, iss, rapida, Moscow, RU, RU
Действителен с 18.01.2011 15:37:14 по 04.10.2014 07:09:41

Расшифрование данных...
Ошибка: Встречено неверное значение тега ASN1.
(0x8009310B)
[ErrorCode: 0x8009310b]

В чем может быть проблема?
Сами функции прилагаю

void MSCrypt::DecryptMessage(std::string &sEncryptedBlobStr,
char *CertMail,
std::string CertSN,
char *psStoreName,
std::string& sDecryptedMessage)
{
static HCRYPTPROV hCryptProv = 0; // дескриптор CSP
static HCERTSTORE hStoreHandle = 0; // дескриптор хранилища сертификатов
static PCCERT_CONTEXT pRecipientCert = NULL;
static char *szDName = NULL; // DName сертификата
std::string str = aria2::Base64::decode(sEncryptedBlobStr);
DWORD cbEncryptedBlob = str.size();
byte *pbEncryptedBlob = (byte*)malloc(cbEncryptedBlob);
pbEncryptedBlob = (byte*)str.c_str();
//memcpy((byte*)str.c_str(), pbEncryptedBlob, cbEncryptedBlob);
DWORD cbDecryptedMessage;
//wchar_t * EncryptedString = NULL;
CRYPT_DECRYPT_MESSAGE_PARA decryptParams;
BYTE* pbDecryptedMessage = NULL;

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, psStoreName);

if(!hStoreHandle)
{
HandleError( "Error getting store handle.");
}
printf("The MY store is open. \n");

// Получение указателя на сертификат получателя с помощью
// функции GetRecipientCert.
pRecipientCert = GetRecipientCert(hStoreHandle, CertMail, CertSN.c_str());

if(!pRecipientCert)
{
printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
printf("property and an AT_KEYEXCHANGE private key available. \n");
printf("While the message could be encrypted, in this case, \n");
printf("it could not be decrypted in this program. \n");
printf("For more information, see the documentation for \n");
printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n");
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);

// Получение указателя на зашифрованное сообщение, pbEncryptedBlob,
// и его длину, cbEncryptedBlob. В этом примере они устанавливаются
// как параметры совместно с CSP и дескриптором открытого хранилища.
// Просмотр зашифрованного BLOBа.
char * ep = getenv("COLUMNS");

int brk;
DWORD i;
brk = ep ? atoi(ep) : 80;
brk = ((brk <= 3) ? 80 : brk) / 3;

//printf("The encrypted string is: \n");
//for(i = 0; i < cbEncryptedBlob; i++)
// printf("%02x%c",pbEncryptedBlob[i],(i%brk == (brk - 1))?'\n':' ');
//printf("\n");

// В этом примере дескриптор хранилище MY установлен как параметр.

// Инициализация структуры CRYPT_DECRYPT_MESSAGE_PARA.
memset(&decryptParams, 0, sizeof(CRYPT_DECRYPT_MESSAGE_PARA));
decryptParams.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
decryptParams.dwMsgAndCertEncodingType = TYPE_DER;
decryptParams.cCertStore = 1;
decryptParams.rghCertStore = &hStoreHandle;

// Расшифрование сообщения

// Вызов фнукции CryptDecryptMessage для получения возвращаемого размера данных.
if(!CryptDecryptMessage(
&decryptParams,
pbEncryptedBlob,
cbEncryptedBlob,
NULL,
&cbDecryptedMessage,
NULL))
{
free(pbEncryptedBlob);
HandleError( "Error getting decrypted message size");
}
printf("The size for the decrypted message is: %d.\n", cbDecryptedMessage);

// Выделение памяти под возвращаемые расшифрованные данные.
pbDecryptedMessage = (BYTE*)malloc(cbDecryptedMessage);
if(!pbDecryptedMessage)
{
free(pbEncryptedBlob);
HandleError("Memory allocation error while decrypting");
}
// Вызов функции CryptDecryptMessage для расшифрования данных.
if(!CryptDecryptMessage(
&decryptParams,
pbEncryptedBlob,
cbEncryptedBlob,
pbDecryptedMessage,
&cbDecryptedMessage,
NULL))
{
free(pbEncryptedBlob);
free(pbDecryptedMessage);
HandleError("Error decrypting the message");
}

printf("Message Decrypted Successfully. \n");
// printf("The decrypted string is: %s\n", (LPSTR) pbDecryptedMessage);
//sDecryptedMessage = "dsfsdfsadf";
sDecryptedMessage.clear();
sDecryptedMessage.append((char*)pbDecryptedMessage, cbDecryptedMessage);
/*if(pbEncryptedBlob)
free(pbEncryptedBlob);
if(pbDecryptedMessage)
free(pbDecryptedMessage); */
return;
}

void MSCrypt::CryptMessage(std::string& sCont,
char* CertMail,
std::string CertSN,
char* psStoreName,
std::string& sEncryptedStr
)
{
static HCRYPTPROV hCryptProv = 0; // дескриптор CSP
static HCERTSTORE hStoreHandle = 0; // дескриптор хранилища сертификатов
static PCCERT_CONTEXT pRecipientCert = NULL;
static char *szDName = NULL; // DName сертификата
BYTE* pbContent = (BYTE*)sCont.c_str(); // Сообщение
DWORD cbContent = (DWORD)(sCont.size()); // Длина сообщения
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;

BYTE* pbEncryptedBlob = NULL;
DWORD cbEncryptedBlob;

printf("source message: %s\n", pbContent);
printf("message length: %d bytes \n", cbContent);

// Получение дескриптора криптографического провайдера.
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, psStoreName);

if(!hStoreHandle)
{
HandleError( "Error getting store handle.");
}
printf("The MY store is open. \n");

// Получение указателя на сертификат получателя с помощью
// функции GetRecipientCert.
pRecipientCert = GetRecipientCert(hStoreHandle, CertMail, CertSN.c_str());

if(!pRecipientCert)
{
printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
printf("property and an AT_KEYEXCHANGE private key available. \n");
printf("While the message could be encrypted, in this case, \n");
printf("it could not be decrypted in this program. \n");
printf("For more information, see the documentation for \n");
printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n");
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 = OID_CipherVar_Default;
EncryptAlgorithm.pszObjId = szOID_CP_GOST_28147;

// Инициализация структуры CRYPT_ENCRYPT_MESSAGE_PARA.
memset(&EncryptParams, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
EncryptParams.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptParams.dwMsgEncodingType = TYPE_DER;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;

// Вызов функции CryptEncryptMessage.
if(!CryptEncryptMessage(
&EncryptParams,
1,
&pRecipientCert,
pbContent,
cbContent,
NULL,
&cbEncryptedBlob))
{
HandleError( "Getting EncrypBlob size failed.");
}
printf("The encrypted message is %d bytes. \n", cbEncryptedBlob);

// Распределение памяти под возвращаемый BLOB.
pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob);

if(!pbEncryptedBlob)
HandleError("Memory allocation error while encrypting.");

// Повторный вызов функции CryptEncryptMessage для зашифрования содержимого.
if(!CryptEncryptMessage(
&EncryptParams,
1,
&pRecipientCert,
pbContent,
cbContent,
pbEncryptedBlob,
&cbEncryptedBlob))
{
HandleError("Encryption failed.");
}

/*char * ep = getenv("COLUMNS");

int brk;

brk = ep ? atoi(ep) : 80;
brk = ((brk <= 3) ? 80 : brk) / 3;*/

//printf("The encrypted string is: \n");
//for(i = 0; i < cbEncryptedBlob; i++)
// printf("%02x%c",pbEncryptedBlob[i],(i%brk == (brk - 1))?'\n':' ');
//printf("\n");
sEncryptedStr.append((char*)pbEncryptedBlob, cbEncryptedBlob);
sEncryptedStr = aria2::Base64::encode(sEncryptedStr);
if(sEncryptedStr.length() != cbEncryptedBlob)
printf("V Encode!!");
printf( "Encryption succeeded. \n");

}

void MSCrypt::SignMessage(std::string &psCont, char *CertMail, std::string CertSN, char *psStoreName, std::string &pbEncodedBlobBase64)
{
Log log("C:\\Server log.txt");
byte *pbEncodedBlob = NULL;
HCRYPTPROV hCryptProv = 0; /* Дескриптор провайдера*/
HCERTSTORE hStoreHandle=0; //Дeскриптор сторе
PCCERT_CONTEXT pRecipientCert = NULL; /* Сертификат, используемый для формирования ЭЦП*/
PCCERT_CONTEXT pRecipientCertArray[1];
DWORD keytype = AT_KEYEXCHANGE; /* Тип ключа (возвращается)*/
HCRYPTMSG hMsg = 0; /* Дескриптор сообщения*/
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; /* Идентификатор алгоритма хэширования*/
DWORD HashAlgSize;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo; /* Структура, описывающая отправителя*/
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1]; /* Массив структур, описывающих отправителя*/
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo; /* Структура, описывающая подписанное сообщение*/
BOOL bReleaseContext;
DWORD flags = 0;
DWORD cbContent = (DWORD)(psCont.size());//длина сообщения
DWORD cbEncodedBlob;
byte *pbContent = (byte*)psCont.c_str();
//--------------------------------------------------------------------
// Начало обработки данных.

//printf("About to begin with the message %s.\n",pbContent);
//printf("The message length is %d bytes. \n", cbContent);

//--------------------------------------------------------------------
// Открытие системного хранилища сертификатов.

//hStoreHandle = CertOpenSystemStore( 0, (LPCSTR)psStoreName);
hStoreHandle = CertOpenSystemStore( 0, "My");
if(hStoreHandle)
{
log.WriteLog("The MY store is open. \n");
}
else
{
HandleError( "Error getting store handle.");
}
//--------------------------------------------------функции GetRecipientCert.
log.WriteLog(CertMail);
log.WriteLog(CertSN);
pRecipientCert = GetRecipientCert(
hStoreHandle, CertMail, CertSN);

if(pRecipientCert)
{
log.WriteLog("A recipient's certificate has been acquired. \n");
}
else
{
log.WriteLog("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
printf("property and an AT_KEYEXCHANGE private key available. \n");
printf("While the message could be sign, in this case, \n");
printf("it could not be veryfy in this program. \n");
printf("For more information, see the documentation \n");
HandleError( "No Certificate with AT_KEYEXCHANGE key in store.");
}
//--------------------------------------------------------------------
// Получение закрытого ключа
if (!CryptAcquireCertificatePrivateKey(pRecipientCert,
0,
NULL,
&hCryptProv,
&keytype,
&bReleaseContext))
{
HandleError( "Cannot acquire the certificate private key");
}
//--------------------------------------------------------------------
// Создание RecipientCertArray.

pRecipientCertArray[0] = pRecipientCert;

//--------------------------------------------------------------------
// Инициализация структуры идентификатора алгоритма.

HashAlgSize = sizeof(HashAlgorithm);

//--------------------------------------------------------------------
// Инициализация структуры с нулем.

memset(&HashAlgorithm, 0, HashAlgSize);

//--------------------------------------------------------------------
// Установка необходимого элемента.

//HashAlgorithm.pszObjId = szOID_CP_GOST_R3411;
printf(":%s; :%d; :%s; :%d;",pRecipientCert->pCertInfo->SignatureAlgorithm.pszObjId, pRecipientCert->pCertInfo->SignatureAlgorithm.pszObjId, szOID_CP_GOST_R3411_R3410EL,szOID_CP_GOST_R3411_R3410EL);

HashAlgorithm.pszObjId = pRecipientCert->pCertInfo->SignatureAlgorithm.pszObjId;
//HashAlgorithm.pszObjId = szOID_CP_GOST_R3411;
//szOID_RSA_SHA1RSA;

/*--------------------------------------------------------------------*/
/* Инициализируем структуру CMSG_SIGNER_ENCODE_INFO*/


memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pRecipientCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = keytype;
// SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;


/*--------------------------------------------------------------------*/
/* Создадим массив отправителей. Сейчас только из одного.*/

SignerEncodeInfoArray[0] = SignerEncodeInfo;

/*--------------------------------------------------------------------*/
/* Инициализируем структуру CMSG_SIGNED_ENCODE_INFO*/

SignerCertBlob.cbData = pRecipientCert->cbCertEncoded;
SignerCertBlob.pbData = pRecipientCert->pbCertEncoded;

/*--------------------------------------------------------------------*/
/* Инициализируем структуру массив структур CertBlob.*/

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 = 0;
SignedMsgEncodeInfo.rgCertEncoded = NULL;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;

/*--------------------------------------------------------------------*/
/* Определим длину подписанного сообщения*/

cbEncodedBlob = CryptMsgCalculateEncodedLength(
TYPE_DER, /* Message encoding type*/
flags, /* Flags*/
CMSG_SIGNED, /* Message type*/
&SignedMsgEncodeInfo, /* Pointer to structure*/
NULL, /* Inner content object ID*/
(DWORD)cbContent); /* Size of content*/
if(cbEncodedBlob)
{
printf("The length of the data has been calculated. \n");
} else
{
HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfoArray[0] = SignerEncodeInfo;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
cbEncodedBlob = CryptMsgCalculateEncodedLength(
TYPE_DER, /* Message encoding type*/
flags, /* Flags*/
CMSG_SIGNED, /* Message type*/
&SignedMsgEncodeInfo, /* Pointer to structure*/
NULL, /* Inner content object ID*/
(DWORD)cbContent); /* Size of content*/
if(cbEncodedBlob)
{
printf("The length of the data has been calculated. \n");
} else
HandleError("Getting cbEncodedBlob length failed.");
}
/*--------------------------------------------------------------------*/
/* Резервируем память, требуемой длины*/

pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob);
if (!pbEncodedBlob)
HandleError("Memory allocation failed");
/*--------------------------------------------------------------------*/
/* Создадим дескриптор сообщения*/
hMsg = CryptMsgOpenToEncode(
TYPE_DER, /* Encoding type*/
flags, /* Flags (CMSG_DETACHED_FLAG )*/
CMSG_SIGNED, /* Message type*/
&SignedMsgEncodeInfo, /* Pointer to structure*/
NULL, /* Inner content object ID*/
NULL); /* Stream information (not used)*/
if(hMsg) {
printf("The message to be encoded has been opened. \n");
} else {
HandleError("OpenToEncode failed");
}
/*--------------------------------------------------------------------*/
/* Поместим в сообщение подписываемые данные*/

if(CryptMsgUpdate(
hMsg, /* Handle to the message*/
pbContent, /* Pointer to the content*/
cbContent, /* Size of the content*/
TRUE)) { /* Last call*/
printf("Content has been added to the encoded message. \n");
} else {
HandleError("MsgUpdate failed");
}
/*--------------------------------------------------------------------*/
/* Вернем подписанное сообщение*/

if(CryptMsgGetParam(
hMsg, /* Handle to the message*/
CMSG_CONTENT_PARAM, /* Parameter type*/
0, /* Index*/
pbEncodedBlob, /* Pointer to the blob*/
&cbEncodedBlob)) { /* Size of the blob*/
printf("Message encoded successfully. \n");
} else {
HandleError("MsgGetParam failed");
}

//освобождение памяти

if(hMsg)
CryptMsgClose(hMsg);
if(hCryptProv && bReleaseContext)
CryptReleaseContext(hCryptProv,0);


pbEncodedBlobBase64.append((char*)pbEncodedBlob, cbEncodedBlob);
pbEncodedBlobBase64 = aria2::Base64::encode(pbEncodedBlobBase64);

//printf("pbEncodedBlob in bas64 is %s \n", pbEncodedBlobBase64.data());
//printf("cbEncodedBlob 1= %d \n", cbEncodedBlob);

}//end of SignMessage

void MSCrypt::VerifyMessage(std::string &pbEncodedBlobBase64, char *CertMail, std::string CertSN, char *psStoreName)
{

HCRYPTPROV hCryptProv = 0; /* Дескриптор провайдера*/
PCCERT_CONTEXT pRecipientCert = NULL; /* Сертификат, используемый для проверки ЭЦП*/
DWORD keytype = 0; /* Возвращаемый тип ключа*/
BOOL should_release_ctx = FALSE;
BYTE *mem_signature = NULL;
size_t signature_len = 0;
HCRYPTMSG hMsg = 0; /* Дескриптор сообщения*/
DWORD cbDecoded;
BYTE *pbDecoded = NULL;
DWORD cbSignerCertInfo = 0;
PCERT_INFO pSignerCertInfo = NULL;
PCCERT_CONTEXT pSignerCertContext = NULL;
PCERT_INFO pSignerCertificateInfo = NULL;
HCERTSTORE hStoreHandle = NULL;
DWORD flags=0;
//char* str = (char*) pbEncodedBlob;
DWORD cbEncodedBlob = 0;
std::string str = aria2::Base64::decode(pbEncodedBlobBase64);
cbEncodedBlob = str.length();
byte *pbEncodedBlob = (byte*)malloc(cbEncodedBlob);
memcpy(pbEncodedBlob, (byte *)str.c_str(), str.length());
//printf("cbEncodedBlob 2= %d\n", cbEncodedBlob);
BYTE *mem_tbs = pbEncodedBlob;
//DWORD cbEncodedBlob = (DWORD)(strlen(pbEncodedBlob)+1);
//printf("cbEncodedBlob = %d\n", cbEncodedBlob);
BOOL bResult;
size_t mem_len = cbEncodedBlob;
if(CryptAcquireContext(
&hCryptProv, // Адрес возврашаемого дескриптора.
NULL,// Используется контейнер Test
NULL, // Используется провайдер по умолчанию.
75, // Необходимо для зашифрования и подписи.
CRYPT_VERIFYCONTEXT)) // Никакие флаги не нужны.
{
printf("A CSP has been acquired. \n");
}
else
{
HandleError("Cryptographic context could not be acquired.");
}
//--------------------------------------------------------------------
// Открытие системного хранилища сертификатов.

hStoreHandle = CertOpenSystemStore( 0, (LPCSTR)psStoreName);

if(hStoreHandle)
{
printf("The MY store is open. \n");
}
else
{
HandleError( "Error getting store handle.");
}
//--------------------------------------------------------------------
// Получение указателя на сертификат издателя с помощью
// функции GetRecipientCert.

pRecipientCert = GetRecipientCert(
hStoreHandle, CertMail, CertSN);
if(pRecipientCert)
{
printf("A recipient's certificate has been acquired. \n");
}
else
{
printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
printf("property and an AT_KEYEXCHANGE private key available. \n");
printf("While the message could be sign, in this case, \n");
printf("it could not be veryfy in this program. \n");
printf("For more information, see the documentation \n");
HandleError( "No Certificate with AT_KEYEXCHANGE key in store.");
}

/*--------------------------------------------------------------------*/
/* Откроем сообщение для декодирования*/

hMsg = CryptMsgOpenToDecode(
TYPE_DER, /* Encoding type.*/
flags, /* Flags.*/
0, /* Use the default message type.*/
hCryptProv, /* Cryptographic provider.*/
NULL, /* Recipient information.*/
NULL); /* Stream information.*/
if (hMsg)
printf("The message to decode is open. \n");
else {
HandleError("OpenToDecode failed");
}

/*--------------------------------------------------------------------*/
/* Поместим в сообщение проверяемые данные*/
bResult = CryptMsgUpdate(
hMsg, /* Handle to the message*/
mem_tbs, /* Pointer to the encoded blob*/
(DWORD)mem_len, /* Size of the encoded blob*/
TRUE); /* Last call*/
if (bResult)
printf("The encoded blob has been added to the message. \n");
else {
HandleError("Decode MsgUpdate failed");
}
/*--------------------------------------------------------------------*/
/* Определим длину подписанных данных*/

bResult = CryptMsgGetParam(
hMsg, /* Handle to the message*/
CMSG_CONTENT_PARAM, /* Parameter type*/
0, /* Signed Index*/
NULL, /* Address for returned info*/
&cbDecoded); /* Size of the returned info*/
if (bResult)
printf("The message parameter (CMSG_CONTENT_PARAM) has been acquired. Message size: %u\n", cbDecoded);
else {
HandleError("Decode CMSG_CONTENT_PARAM failed");
}

/*--------------------------------------------------------------------*/
/* Резервируем память*/
pbDecoded = (BYTE *) malloc(cbDecoded);
if (!pbDecoded)
HandleError("Decode memory allocation failed");
/*--------------------------------------------------------------------*/
/* Вернем подписанные данные*/

bResult = CryptMsgGetParam(
hMsg, /* Handle to the message*/
CMSG_CONTENT_PARAM, /* Parameter type*/
0, /* Signer Index*/
pbDecoded, /* Address for returned info*/
&cbDecoded); /* Size of the returned info*/
if (bResult)
printf("The message param (CMSG_CONTENT_PARAM) returned. Length is %lu.\n", (unsigned long)cbDecoded);
else
{
HandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}
for(int i = 0; i < cbDecoded; i++)
printf("%d - %c\n", i, pbDecoded[i]);




/*--------------------------------------------------------------------*/
/* Проверка ЭЦП*/
/* Сначала определим информация CERT_INFO об отправителе.*/

/*--------------------------------------------------------------------*/
/* Если сертификат задан */
/* создадим справочник в памяти с этим сертификатом.*/
/* Это сделано только для того, чтобы затем вернуть сертификат функцией */
/* CertGetSubjectCertificateFromStore, которая также используется, если*/
/* сертификат отправителя находится в самом сообщении.*/
if (pRecipientCert) {
hStoreHandle = CertOpenStore(CERT_STORE_PROV_MEMORY, TYPE_DER, 0, CERT_STORE_CREATE_NEW_FLAG,NULL);
if (!hStoreHandle)
HandleError("Cannot create temporary store in memory.");
/* Добавим сертификат в справочник*/
if (pRecipientCert) {
bResult = CertAddCertificateContextToStore(hStoreHandle, pRecipientCert, CERT_STORE_ADD_ALWAYS, NULL);
pSignerCertInfo = pRecipientCert->pCertInfo;
} else
bResult = 0;
if (!bResult) {
HandleError("Cannot add user certificate to store.");
}
}
/*--------------------------------------------------------------------*/
/* Найдем сертификат отправителя в справочнике*/

pSignerCertContext = CertGetSubjectCertificateFromStore(
hStoreHandle, /* Handle to store*/
TYPE_DER, /* Encoding type*/
pSignerCertInfo);
if(pSignerCertContext) { /* Pointer to retrieved CERT_CONTEXT*/
printf("A signer certificate has been retrieved.");
} else {
HandleError("Verify GetSubjectCert failed");
}

/*--------------------------------------------------------------------*/

/* Используя структуру CERT_INFO проверяем ЭЦП сообщения*/
pSignerCertificateInfo = pSignerCertContext->pCertInfo;
bResult = CryptMsgControl(
hMsg, /* Handle to the message*/
0, /* Flags*/
CMSG_CTRL_VERIFY_SIGNATURE, /* Control type*/
pSignerCertificateInfo); /* Pointer to the CERT_INFO*/
if(bResult) {
printf("\nSignature was VERIFIED.\n");
} else {
printf("\nThe signature was NOT VERIFIED.\n");
}
//освобождение памяти
CertFreeCertificateContext(pRecipientCert);
if(CertCloseStore(
hStoreHandle,
CERT_CLOSE_STORE_CHECK_FLAG))
{
printf("The MY store was closed without incident. \n");
}
else
{
printf("Store closed after encryption but \n not all certificates or CRLs were freed. \n");
}
if(hMsg)
CryptMsgClose(hMsg);
if(hCryptProv)
CryptReleaseContext(hCryptProv,0);
}//end of VerifyMessage


// В этом примере используется функция HandleError, функция обработки
// простых ошибок, для печати сообщения об ошибке в стандартный файл
// ошибок (stderr) и выхода из программы.
// В большинстве приложений эта функция заменяется другой функцией,
// которая выводит более полное сообщение об ошибке.
Offline Kirill Sobolev  
#2 Оставлено : 18 марта 2011 г. 14:05:49(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Код:

aria2::Base64::decode
aria2::Base64::encode

попробуйте без этих вызовов
Техническую поддержку оказываем тут
Наша база знаний
Offline MipT.Shurik  
#3 Оставлено : 18 марта 2011 г. 17:10:27(UTC)
MipT.Shurik

Статус: Участник

Группы: Участники
Зарегистрирован: 15.10.2010(UTC)
Сообщений: 10
Откуда: Moscow

Kirill Sobolev написал:
Код:

aria2::Base64::decode
aria2::Base64::encode

попробуйте без этих вызовов


Пробовал уже

//освобождение памяти

if(hMsg)
CryptMsgClose(hMsg);
if(hCryptProv && bReleaseContext)
CryptReleaseContext(hCryptProv,0);

FILE *stream;
stream = fopen("C:\\binsign", "w");
fwrite((char*)pbEncodedBlob, 1, cbEncodedBlob, stream);
fclose(stream);


pbEncodedBlobBase64.append((char*)pbEncodedBlob, cbEncodedBlob);
pbEncodedBlobBase64 = aria2::Base64::encode(pbEncodedBlobBase64);

//printf("pbEncodedBlob in bas64 is %s \n", pbEncodedBlobBase64.data());
//printf("cbEncodedBlob 1= %d \n", cbEncodedBlob);

}//end of SignMessage


Получаю


c:\TEMP\distr\cryptcp>cryptcp.exe -verify -f ayush.cer -nochain binsign binsignout
CryptCP 3.33 (c) "Крипто-Про", 2002-2010.
Утилита командной строки для защиты данных.
-verify - Проверка цифровых подписей.

Будет использован следующий сертификат:
Субъект:ayushchenko@rapida.ru, ayushchenko, iss, rapida, Moscow, RU, RU
Действителен с 18.01.2011 15:37:14 по 04.10.2014 07:09:41

Проверка подписи...
Ошибка: Ошибка при обработке криптографического сообщения.
(0x80091001)
[ErrorCode: 0x80091001]

Отредактировано пользователем 18 марта 2011 г. 17:11:01(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#4 Оставлено : 18 марта 2011 г. 18:31:25(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Перед этим у Вас шифрование не работало, а сейчас подпись не проверяется.
По подписи:
Код:
HashAlgorithm.pszObjId = pRecipientCert->pCertInfo->SignatureAlgorithm.pszObjId;
HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;

Вот это неправильно, а правильный вариант как раз в комментариях.
Код:
//HashAlgorithm.pszObjId = szOID_CP_GOST_R3411;

Техническую поддержку оказываем тут
Наша база знаний
Offline MipT.Shurik  
#5 Оставлено : 18 марта 2011 г. 19:05:48(UTC)
MipT.Shurik

Статус: Участник

Группы: Участники
Зарегистрирован: 15.10.2010(UTC)
Сообщений: 10
Откуда: Moscow

Kirill Sobolev написал:
Перед этим у Вас шифрование не работало, а сейчас подпись не проверяется.
По подписи:
Код:
HashAlgorithm.pszObjId = pRecipientCert->pCertInfo->SignatureAlgorithm.pszObjId;
HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;

Вот это неправильно, а правильный вариант как раз в комментариях.
Код:
//HashAlgorithm.pszObjId = szOID_CP_GOST_R3411;


и подпись cryptcp не может проверить и расшифровать не может.

c:\TEMP\distr\cryptcp>cryptcp.exe -verify -f ayush.cer -nochain binsign binsignout
CryptCP 3.33 (c) "Крипто-Про", 2002-2010.
Утилита командной строки для защиты данных.
-verify - Проверка цифровых подписей.

Будет использован следующий сертификат:
Субъект:ayushchenko@rapida.ru, ayushchenko, iss, rapida, Moscow, RU, RU
Действителен с 18.01.2011 15:37:14 по 04.10.2014 07:09:41

Проверка подписи...
Ошибка: Ошибка при обработке криптографического сообщения.
(0x80091001)
[ErrorCode: 0x80091001]

если так поставить HashAlgorithm.pszObjId = szOID_CP_GOST_R3411, то будет ли тогда поддерживать SHA1RSA?


Offline Kirill Sobolev  
#6 Оставлено : 18 марта 2011 г. 19:09:25(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Цитата:
то будет ли тогда поддерживать SHA1RSA?

А Вы по какому алгоритму подпись делаете?
Техническую поддержку оказываем тут
Наша база знаний
Offline MipT.Shurik  
#7 Оставлено : 18 марта 2011 г. 19:38:46(UTC)
MipT.Shurik

Статус: Участник

Группы: Участники
Зарегистрирован: 15.10.2010(UTC)
Сообщений: 10
Откуда: Moscow

Kirill Sobolev написал:
Цитата:
то будет ли тогда поддерживать SHA1RSA?

А Вы по какому алгоритму подпись делаете?

По госту, но если допустим сертификат не выпущен для госта, то тогда я не смогу подписать с помощью своей функции. Проверял.
Вложение(я):
binsign (1kb) загружен 21 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
Offline Kirill Sobolev  
#8 Оставлено : 18 марта 2011 г. 20:38:11(UTC)
Кирилл Соболев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,733
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
у binsign битая структура - ASN.1 не парсится.
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.