logo Обзор КриптоПро NGate для защищённого доступа к корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Treno1  
#1 Оставлено : 30 июля 2012 г. 18:37:48(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

Добрый день!

Проблема такова: Подписываю файл с помощью CryptSignMessage, записываю подпись в файл, но не криптоАрм не csptest подпись не понимают. csptest выдаёт "В ASN1 встречен неожиданный конец данных". Самописная программа с CryptVerifyDetachedMessageSignature подпись понимает и считает valid`ной. Чего я сделал не правильно?

Код:

    SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
    SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
    SigParams.pSigningCert = pSignerCert;
    SigParams.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
    SigParams.HashAlgorithm.Parameters.cbData = NULL;
    SigParams.cMsgCert = 1;
    SigParams.rgpMsgCert = &pSignerCert;
    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,
        TRUE,
        1,
        MessageArray,
        MessageSizeArray,
        NULL,
        &cbSignedMessageBlob))
    {
        _tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"),
            cbSignedMessageBlob);
    }
    else
    {
        MyHandleError(TEXT("Getting signed BLOB size failed"));
        goto exit_SignMessage;
    }

    // Allocate memory for the signed BLOB.
    if(!(pbSignedMessageBlob = 
       (BYTE*)malloc(cbSignedMessageBlob)))
    {
        MyHandleError(
            TEXT("Memory allocation error while signing."));
        goto exit_SignMessage;
    }

    // Get the signed message BLOB.
    if(CryptSignMessage(
          &SigParams,
          TRUE,
          1,
          MessageArray,
          MessageSizeArray,
          pbSignedMessageBlob,
          &cbSignedMessageBlob))
    {
        _tprintf(TEXT("The message was signed successfully. \n"));

        // pbSignedMessageBlob now contains the signed BLOB.
        fReturn = 1;
    }
    else
    {
        MyHandleError(TEXT("Error getting signed BLOB"));
        goto exit_SignMessage;
    }



    if(pbSignedMessageBlob)
    {
		char buf[256] = {NULL};
		outfile_f = fopen(outfile, "wb");
			if(!outfile_f) {
				return(0);
			}
		strcpy(buf,(char*)pbSignedMessageBlob);
		strcat(buf,"\0");
		fprintf(outfile_f, buf); 
		fclose(outfile_f);
	}
Offline Андрей Писарев  
#2 Оставлено : 30 июля 2012 г. 18:50:01(UTC)
Андрей Писарев

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 8,343
Мужчина

Сказал «Спасибо»: 292 раз
Поблагодарили: 1168 раз в 921 постах
ну и где кусок по заполнению памяти данными?
MessageArray

судя по блоку:
Цитата:
char buf[256]

char передаешь? и правильно, что не понимают другие средства для проверки ЭЦП...

ps. byte* нужно ...

Отредактировано пользователем 30 июля 2012 г. 18:53:05(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Treno1  
#3 Оставлено : 30 июля 2012 г. 18:59:05(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

Полный код ниже.

А разве есть разница какой тип данный записывать в файл?

Цитата:
int SignMessage(CRYPT_DATA_BLOB *pSignedMessageBlob,char* infile,char* outfile,char* signer_name)
{
int fReturn = 0;
BYTE* pbMessage;
DWORD cbMessage;
HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pSignerCert;
CRYPT_SIGN_MESSAGE_PARA SigParams;
DWORD cbSignedMessageBlob;
BYTE *pbSignedMessageBlob = NULL;
const BYTE* MessageArray[] = {"\0"};
DWORD_PTR MessageSizeArray[1];
FILE *infile_f;
char infile_str[512] = {'\0'};
FILE *outfile_f;
wchar_t *convCp_wbuf = NULL;
unsigned short convCp_wbuf_len;
LPCSTR lpszCertSubject;

convCp_wbuf_len = MultiByteToWideChar( CP_ACP , 0, signer_name, -1, NULL, 0);
convCp_wbuf = calloc( sizeof( wchar_t ) , convCp_wbuf_len );

if(MultiByteToWideChar( CP_ACP, 0, signer_name, -1, convCp_wbuf, convCp_wbuf_len)){
lpszCertSubject = (LPCSTR)convCp_wbuf;
}

infile_f = fopen(infile, "rb");
if(!infile_f) {
return(0);
}

while(!feof(infile_f))
{
fgets(infile_str, 512, infile_f);
pbMessage = (BYTE*)infile_str;
}
MessageArray[0] = pbMessage;
fclose(infile_f);
// Initialize the output pointer.
pSignedMessageBlob->cbData = 0;
pSignedMessageBlob->pbData = NULL;

// 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);

MessageSizeArray[0] = cbMessage;

// Begin processing.
_tprintf(TEXT("The message to be signed is \"%s\".\n"),
pbMessage);

// Open the certificate store.
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
CERT_STORE_NAME)))
{
MyHandleError(TEXT("The MY store could not be opened."));
goto exit_SignMessage;
}

//MultiByteToWideChar(CP_ACP, 0, signer_name, strlen(signer_name)+1, signer_name,strlen(signer_name)+1);

// Get a pointer to the signer's certificate.
// This certificate must have access to the signer's private key.
if(pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
lpszCertSubject,
NULL))
{
_tprintf(TEXT("The signer's certificate was found.\n"));
}
else
{
MyHandleError( TEXT("Signer certificate not found."));
goto exit_SignMessage;
}

// Initialize the signature structure.
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
SigParams.pSigningCert = pSignerCert;
SigParams.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
SigParams.HashAlgorithm.Parameters.cbData = NULL;
SigParams.cMsgCert = 1;
SigParams.rgpMsgCert = &pSignerCert;
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,
TRUE,
1,
MessageArray,
MessageSizeArray,
NULL,
&cbSignedMessageBlob))
{
_tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"),
cbSignedMessageBlob);
}
else
{
MyHandleError(TEXT("Getting signed BLOB size failed"));
goto exit_SignMessage;
}

// Allocate memory for the signed BLOB.
if(!(pbSignedMessageBlob =
(BYTE*)malloc(cbSignedMessageBlob)))
{
MyHandleError(
TEXT("Memory allocation error while signing."));
goto exit_SignMessage;
}

// Get the signed message BLOB.
if(CryptSignMessage(
&SigParams,
TRUE,
1,
MessageArray,
MessageSizeArray,
pbSignedMessageBlob,
&cbSignedMessageBlob))
{
_tprintf(TEXT("The message was signed successfully. \n"));

// pbSignedMessageBlob now contains the signed BLOB.
fReturn = 1;
}
else
{
MyHandleError(TEXT("Error getting signed BLOB"));
goto exit_SignMessage;
}

exit_SignMessage:

// Clean up and free memory as needed.
if(pSignerCert)
{
CertFreeCertificateContext(pSignerCert);
}

if(hCertStore)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
hCertStore = NULL;
}

// Only free the signed message if a failure occurred.
if(!fReturn)
{
if(pbSignedMessageBlob)
{
free(pbSignedMessageBlob);
pbSignedMessageBlob = NULL;
}
}

if(pbSignedMessageBlob)
{
char buf[256] = {NULL};
outfile_f = fopen(outfile, "wb");
if(!outfile_f) {
return(0);
}
strcpy(buf,(char*)pbSignedMessageBlob);
strcat(buf,"\0");
fprintf(outfile_f, buf);
fclose(outfile_f);
}

return fReturn;
}
Offline Treno1  
#4 Оставлено : 31 июля 2012 г. 16:44:28(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

Решено: добавлением подписи по ГОСТу ,
Код:
SigParams.HashAlgorithm.pszObjId = szOID_GostR3411_94_CryptoProParamSet;

Удалением лишних +1 к хешу,
Правильной записью в файл,
Код:
fwrite(pbSignedMessageBlob,sizeof(BYTE),cbSignedMessageBlob,outfile_f);


Единственное что, я не нашёл как проверять сертификат на отозванность и доверенность.
Offline Андрей Писарев  
#5 Оставлено : 31 июля 2012 г. 16:53:10(UTC)
Андрей Писарев

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 8,343
Мужчина

Сказал «Спасибо»: 292 раз
Поблагодарили: 1168 раз в 921 постах
Treno1 написал:
Решено: добавлением подписи по ГОСТу ,
Код:
SigParams.HashAlgorithm.pszObjId = szOID_GostR3411_94_CryptoProParamSet;

Удалением лишних +1 к хешу,
Правильной записью в файл,
Код:
fwrite(pbSignedMessageBlob,sizeof(BYTE),cbSignedMessageBlob,outfile_f);


Единственное что, я не нашёл как проверять сертификат на отозванность и доверенность.


Applause

szOID_GostR3411_94_CryptoProParamSet - конечно, а если будет сертификат RSA ? Anxious

(по первому куску кода хотел было спросить... а если будет не RSA Anxious )

Отредактировано пользователем 31 июля 2012 г. 16:55:36(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Treno1  
#6 Оставлено : 31 июля 2012 г. 17:13:59(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

szOID_OIWSEC_sha1RSASign криптоАрм тоже дал успех.

Ещё вот такой вопрос:

В моей функции проверки я думаю что слишком много мусора, но без него ничего не работает.

Вот что я думаю что мусор:
Код:
if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
        MY_ENCODING_TYPE,     // Message encoding type
        0,                    // Flags
        CMSG_SIGNED,          // Message type
        &SignedMsgEncodeInfo, // Pointer to structure
        NULL,                 // Inner content OID
        cbContent)))          // Size of content
    {
        MyHandleError("Getting cbEncodedBlob length failed.");
    }

    //---------------------------------------------------------------
    // Allocate memory for the encoded BLOB.
    if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
    {
        MyHandleError("Malloc operation failed.");
    }
	
	
	//---------------------------------------------------------------
    // Open a message to encode.
    if(!(hMsg = CryptMsgOpenToEncode(
        MY_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("OpenToEncode failed");
    }

    //---------------------------------------------------------------
    // 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("MsgUpdate failed");
    }

    //---------------------------------------------------------------
    // 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("MsgGetParam failed.");
    }
	
	
    //---------------------------------------------------------------
    // The message is signed and encoded.
    // Close the message handle and the certificate store.
    CryptMsgClose(hMsg);
    CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
    CryptReleaseContext(hCryptProv, 0);


Получаеться что я заного создаю подпись и потом вставляю в pbEncodedBlob то , что считал с файла. Это наверное не правильно.

Когда я считываю из .sig файла то получаю cbEncodedBlob 1388, а программа получает для новой подписи cbEncodedBlob 1408 и выделяет память на pbEncodedBlob 1408, а потом через CryptMsgGetParam делает 1388 в cbEncodedBlob. Это всё посылаеться в CryptVerifyDetachedMessageSignature и получаю valid.

Если я убираю "мусор" и выделяю 1388 памяти под pbEncodedBlob и записиваю туда всё что считал из файла то в CryptVerifyDetachedMessageSignature я получаю CRYPT_E_ASN1_BADTAG или CRYPT_E_ASN1_EOD.

Что делать с мусором?
Offline Андрей Писарев  
#7 Оставлено : 31 июля 2012 г. 17:19:15(UTC)
Андрей Писарев

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 8,343
Мужчина

Сказал «Спасибо»: 292 раз
Поблагодарили: 1168 раз в 921 постах
Это не мусор


Низкоуровневые vs Высокоуровневые функции

определять тебе, какие использовать...

Отредактировано пользователем 31 июля 2012 г. 17:21:14(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Treno1  
#8 Оставлено : 31 июля 2012 г. 17:28:46(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

Получаеться что я заного создаю подпись и потом вставляю в pbEncodedBlob то , что считал с файла. Это наверное не правильно?
Offline Treno1  
#9 Оставлено : 31 июля 2012 г. 18:01:39(UTC)
Treno1

Статус: Активный участник

Группы: Участники
Зарегистрирован: 30.07.2012(UTC)
Сообщений: 34

Решено без "мусора":

Код:
int VerifySignedMessage(
    char* infile,char* outfile)
{
    int fReturn = 0;
    CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
	FILE *infile_f;
	char infile_str[512] = {'\0'};
	char tmpi[512] = {NULL};
	char outfile_str[512] = {'\0'};
	char* tmpo;
	FILE *outfile_f;
	BYTE* pbContent;
    DWORD cbContent;
	DWORD cbpb;
	DWORD cbEncodedBlob;
    BYTE* pbEncodedBlob;
	HCRYPTPROV hCryptProv;         // CSP handle
    HCERTSTORE hStoreHandle;       // Store handle
    PCCERT_CONTEXT pSignerCert;    // Signer certificate

    CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
    CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
    CERT_BLOB SignerCertBlob;
    CERT_BLOB SignerCertBlobArray[1];
    CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
    HCRYPTMSG hMsg;
    DWORD dwKeySpec;
	CRYPT_VERIFY_MESSAGE_PARA msgPara;

	long lSize;

	outfile_f = fopen(outfile, "rb");
	if(!outfile_f) {
        return(0);
	}

	fseek (outfile_f , 0 , SEEK_END);
	lSize = ftell (outfile_f);
	rewind (outfile_f);

	tmpo = (char*) malloc (sizeof(char)*lSize);
	
	// copy the file into the buffer:
	cbEncodedBlob = fread (tmpo,1,lSize,outfile_f);
	if (cbEncodedBlob != lSize) {
		return(0);
	}

	infile_f = fopen(infile, "rb");
	if(!infile_f) {
        return(0);
	}

	while(!feof(infile_f))
	{
		fgets(infile_str, 512, infile_f);
		strcat(tmpi,infile_str);
	}
	pbContent = (BYTE*)tmpi;
	cbContent = strlen((char *) pbContent);
	cbpb = strlen((char *)tmpo);
	
    //---------------------------------------------------------------
    // Allocate memory for the encoded BLOB.
    if(!(pbEncodedBlob = (BYTE *) malloc(cbpb)))
    {
        MyHandleError("Malloc operation failed.");
    }
	
	pbEncodedBlob = (BYTE*)tmpo;
	
	msgPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
    msgPara.dwMsgAndCertEncodingType = 
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
    msgPara.hCryptProv = NULL;
    msgPara.pfnGetSignerCertificate = NULL;
    msgPara.pvGetArg = NULL;

    if ( CryptVerifyDetachedMessageSignature(
                                             &msgPara,
                                             0,
                                             pbEncodedBlob,
                                             cbEncodedBlob,
                                             1,
                                             &pbContent,
                                             &cbContent,
                                             NULL
                                            ) )
    {
        printf("The Signature verified.\n");
		free(pbEncodedBlob);
		fReturn = 1;
    }
    else
    {	
		DWORD tmp;
		tmp = GetLastError();
		if(GetLastError() == CRYPT_E_ASN1_BADTAG)
			printf("1");
		if(GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE)
			printf("2");
		if(GetLastError() == CRYPT_E_NO_SIGNER)
			printf("3");
		if(GetLastError() == NTE_BAD_ALGID)
			printf("4");
		if(GetLastError() == NTE_BAD_SIGNATURE)
			printf("5");
		if(GetLastError() == CRYPT_E_ASN1_EOD)
			printf("6");
        printf("Verification message failed.\n");
    }

    return fReturn;
}


А теперь мне надо чтобы сертификат из detached файла проверялся на отозванность и доверие. Как я понял нужно последним параметром в CryptVerifyDetachedMessageSignature передать указатель на сертификат и с ним работать. Спасибо!
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.