22.10.2004 10:57:02Функция CryptEncodeObject Ответов: 4
Дмитрий
Необходимо сохранить подпись в файл в формате PKCS#7
Делаю следующим образом:
...
CryptSignHash(hash, AT_KEYEXCHANGE, nil, 0, signature, @size)

CryptGetUserKey(hProv, AT_KEYEXCHANGE, @hUserKey);
CryptGetKeyParam(hUserKey, KP_CERTIFICATE, nil, @dwUserCertLength, 0);
SetLength(pbUserCert,dwUserCertLength);
CryptGetKeyParam (hUserKey, KP_CERTIFICATE, Pointer(pbUserCert), @dwUserCertLength, 0);

PCRT:=CertCreateCertificateContext(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, Pointer(pbUserCert), dwUserCertLength);

signer.Issuer:= PCRTC.pCertInfo.Issuer;
signer.SerialNumber:= PCRTC.pCertInfo.SerialNumber;
signer.EncryptedHash.pbData:= signature;
signer.EncryptedHash.cbData:= size;
signer.AuthAttrs.cAttr:= 0;
signer.AuthAttrs.rgAttr:= nil;
signer.UnauthAttrs.cAttr:= 0;
signer.UnauthAttrs.rgAttr:= nil;

CryptEncodeObject(PKCS_7_ASN_ENCODING,
PKCS7_SIGNER_INFO,@signer,nil,@sizePKCS)GetMem(signaturePKCS, sizePKCS);
CryptEncodeObject(PKCS_7_ASN_ENCODING,
PKCS7_SIGNER_INFO,@signer,signaturePKCS,@sizePKCS)

BlockWrite(hshfile, signaturePKCS^, size);
CloseFile(hshfile);

Буфер с подписью почему-то имеет такой же размер - 64 байта, как и просто после СryptSignHash, хотя должен быть больше.
Подскажиьте, please, что я не так делаю?
Заранее благодарен.
 
Ответы:
22.10.2004 11:10:41Дмитрий
извиняюсь, в конце будет
BlockWrite(hshfile, signaturePKCS^, sizePKCS);
CloseFile(hshfile);

Буфер с подписью реально больше,
но теперь проверка подписи говорит, что подпись не верна.
22.10.2004 11:51:01Serge3leo
Здравствуйте,

Очевидно, что Вы не устанавливаете всего для PCRTC.

Нужно установить hProv и AT_KEYEXCHANGE в свойства PCRTC.

Успехов
22.10.2004 12:07:35Дмитрий
да, нет устанавливаю, там выше отрабатывают функции
CryptAcquireContext()
CryptCreateHash(hProv, alg, 0, 0, @hash)
CryptHashData(hash, @buf, size, 0)

Я думал дело еще в параметрах стр-ры signer:
signer.dwVersion
signer.HashAlgorithm и
signer.HashEncryptionAlgorithm

Пробую так
signer.dwVersion:= PCRT.pCertInfo.dwVersion
signer.HashAlgorithm.pszObjId:= szOID_CP_GOST_R3411;
signer.HashEncryptionAlgorithm.pszObjId:= szOID_PKCS_7;

Это правильно? и что писать в
signer.HashAlgorithm.Parameters и
signer.HashEncryptionAlgorithm.Parameters
22.10.2004 12:25:33Serge3leo
Здравствуйте,

Хм. Да Вы не используете CryptSignMessage, а пытаетесь сами сформировать CMS сообщение, соотвественно Вам не нужно, что бы контекст сертификата ссылался на ключ.

Рекомендую воспользоваться, оно само сделает. Аналогичный вопрос обсуждается в "Вопрос про АРМ разбора конфликтов" <http://www.cryptopro.ru/CryptoPro/forum/myforum.asp?q=1258>

А по существу, Вы формируете только SignerInfo. А подписью будет являтся SignedData, см. RFC 3369

SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos }

Успехов.