Есть процедурка которая должна по идее подписать файлик указанным сертификатом, но что-то у меня вылетает ошибочка "нет ключей". Что может быть за проблема?
может я чего не догоняю?
Использую провайдер от КриптоПро.
procedure Sign(data: TStream; rslt: TStream; signer_cert: PCCERT_CONTEXT; sz_oid: PChar; DetachedSignature: Boolean);
var pSignPara: PCRYPT_SIGN_MESSAGE_PARA;
MessageArray: array[0..0] of PByte;
MessageSizeArray: array[0..0] of Dword;
pbSignedMessageBlob, pbMessageBlob: PByte;
cbSignedMessageBlob: Dword;
keyContext : CERT_KEY_CONTEXT;
keyProvInfo: CRYPT_KEY_PROV_INFO;
hProv: HCRYPTPROV;
begin
New(pSignPara);
ZeroMemory(pSignPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA));
if not CryptAcquireContext(@hProv, nil, PROVIDER_NAME, PROVIDER_TYPE,CRYPT_VERIFYCONTEXT) then
begin
///Ченить написать для обработке
exit;
end;
keyProvInfo.pwszContainerName := Str2WChar(GetContainerName);
keyProvInfo.pwszProvName := Str2Wchar(GetProviderName);
keyProvInfo.dwProvType := GetProviderType;
keyProvInfo.dwFlags := 0;
keyProvInfo.cProvParam := 0;
keyProvInfo.dwKeySpec := AT_KEYEXCHANGE;
CertSetCertificateContextProperty(signer_cert,CERT_KEY_PROV_INFO_PROP_ID, 0, @keyprovInfo);
keyContext.hCryptProv := CryptContext.Provider;
keyContext.dwKeySpec := AT_KEYEXCHANGE;
keyContext.cbSize := sizeof(CERT_KEY_CONTEXT);
CertSetCertificateContextProperty( signer_cert, CERT_KEY_CONTEXT_PROP_ID,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
@keyContext);
pSignPara.dwMsgEncodingType := X509_ASN_ENCODING or PKCS_7_ASN_ENCODING;
pSignPara.cbSize := sizeof(CRYPT_SIGN_MESSAGE_PARA);
pSignPara.pSigningCert := signer_cert;
pSignPara.HashAlgorithm.pszObjId := sz_oid;
pSignPara.cMsgCert := 1;
pSignPara.rgpMsgCert := @signer_cert;
MessageSizeArray[0] := data.Size - data.Position;
GetMem(pbMessageBlob, data.Size - data.Position);
data.Read(pbMessageBlob^, data.Size-data.Position);
MessageArray[0] := pbMessageBlob;
cbSignedMessageBlob := 0;
if(not CryptSignMessage(
pSignPara,
DetachedSignature,
1,
Addr(MessageArray),
Cardinal(Addr(MessageSizeArray)),
nil,
@cbSignedMessageBlob))
then
raise TCryptException.Create(ceOtherCryptError);
GetMem(pbSignedMessageBlob,cbSignedMessageBlob);
if(not CryptSignMessage(
pSignPara,
DetachedSignature,
1,
Addr(MessageArray),
Cardinal(Addr(MessageSizeArray)),
pbSignedMessageBlob,
@cbSignedMessageBlob))
then
raise TCryptException.Create(ceOtherCryptError);
rslt.Write(pbSignedMessageBlob^, cbSignedMessageBlob);
end;