Answer the question
In order to leave comments, you need to log in
How to use digital signature in .p12 file in Delphi?
There is an EDS in PKCS12 format. It is necessary to read the certificate, determine the owner, the relevance of the certificate (date of issue, date of expiration). It is solved, I think that through OpenSSL. Have you seen wrappers for functions, optimized headers for Delphey, ready-made working code for examples?
Answer the question
In order to leave comments, you need to log in
Solved a similar problem using CryptoCSP from CryptoPro ( documentation on the topic ). This is a wrapper for working with certificates, you can try to work through Microsoft's CryptoAPI if you figure it out.
I give a couple of examples so that you understand in which direction to move:
Example 1.
// Пример работы с сертификатами. Поиск по номеру сертификата.
// В дельфи номер пишется в обратном порядке!
class function TDigitalSigner.GetCertificateBySerialNumber(const aSerialNumber: string): PCCERT_CONTEXT;
var
hStore: hcertstore;
begin
hStore := CertOpenSystemStore(0, 'MY');
Result := CertFindCertificateInStore(hStore, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, PChar(aSerialNumber), nil);
end;
function EncryptAndSign(ASignCertContent: string; AEncCerts: TStringList; FileName, OutFileName: string; out ErrText: string): Boolean;
var
hProv : HCRYPTPROV;
hStoreHandle: hcertstore;
pSignerCert : jwawincrypt.PCCERT_CONTEXT;
encCert : jwawincrypt.CRYPT_DATA_BLOB;
SigParams : jwawincrypt.CRYPT_SIGN_MESSAGE_PARA;
pCertContext: PCCERT_CONTEXT;
Stream : TMemoryStream;
Certificates: array [0 .. 100] of PCCERT_CONTEXT;
EncParams : CRYPT_ENCRYPT_MESSAGE_PARA;
cbEncrypted : DWORD;
i : integer;
pszObjId : LPSTR;
const
PROV_GOST_2001_DH = 75;
begin
Result := false;
for i := 0 to 100 do
Certificates[i] := nil;
if not jwawincrypt.CryptAcquireContext(hProv, nil, nil, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT) then
exit;
hStoreHandle := CertOpenSystemStore(hProv, 'MY');
if (hStoreHandle = nil) then
begin
ErrText := 'ErrorOpenStore';
exit;
end;
for i := 0 to AEncCerts.Count - 1 do
begin
try
encCert := GetCertContent(FileToStr(AEncCerts.Strings[i]));
except
ErrText := 'ErrorCertLoad';
Continue;
end;
pCertContext := jwawincrypt.CertCreateCertificateContext(MYTYPE, encCert.pbData, encCert.cbData);
pCertContext := jwawincrypt.CertFindCertificateInStore(hStoreHandle, MYTYPE, 0, CERT_FIND_EXISTING, pCertContext, nil);
if (pCertContext = nil) then
begin
ErrText := 'ErrorCertInStoreNotFound';
Continue;
end;
Certificates[i] := pCertContext;
end;
encCert := GetCertContent(FileToStr(ASignCertContent));
// Открываем хранилище сертификатов
pSignerCert := nil;
pSignerCert := jwawincrypt.CertCreateCertificateContext(MYTYPE, encCert.pbData, encCert.cbData);
pSignerCert := jwawincrypt.CertFindCertificateInStore(hStoreHandle, MYTYPE, 0, CERT_FIND_EXISTING, pSignerCert, nil);
if (pSignerCert = nil) then
begin
exit;
end;
with TMemoryStream.Create do
try
LoadFromFile(FileName);
try
try
// Инициализация структуры, необходимой для цифровой подписи
pszObjId := szOID_RSA_MD5; // получение алгоритма сертификата
FillChar(SigParams, Sizeof(CRYPT_SIGN_MESSAGE_PARA), #0);
SigParams.cbSize := Sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType := MYTYPE;
SigParams.pSigningCert := pSignerCert;
SigParams.HashAlgorithm.pszObjId := pszObjId;
// для Сигнал - Com szOID_RSA_MD5;// 1.2.643.2.2.21
SigParams.HashAlgorithm.Parameters.cbData := 0;
SigParams.cMsgCert := 1;
SigParams.rgpMsgCert := @pSignerCert;
SigParams.cAuthAttr := 0;
SigParams.dwInnerContentType := 0;
SigParams.cMsgCrl := 0;
SigParams.cUnauthAttr := 0;
SigParams.dwFlags := 0;
SigParams.pvHashAuxInfo := nil;
SigParams.rgAuthAttr := nil;
ZeroMemory(@EncParams, Sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
EncParams.cbSize := Sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncParams.dwMsgEncodingType := MYTYPE;
EncParams.HCRYPTPROV := hProv;
EncParams.ContentEncryptionAlgorithm.pszObjId := szOID_CP_GOST_28147;
// Алгоритм шифрования ГОСТ 28147-89 1.2.643.2.2.21
if CryptSignAndEncryptMessage(@SigParams, @EncParams, AEncCerts.Count, @Certificates, Memory, Size, nil, cbEncrypted) then
begin
Stream := TMemoryStream.Create;
try
Stream.SetSize(cbEncrypted);
if CryptSignAndEncryptMessage(@SigParams, @EncParams, AEncCerts.Count, @Certificates, Memory, Size, Stream.Memory, cbEncrypted) then
begin
Stream.SetSize(cbEncrypted);
Stream.SaveToFile(OutFileName);
Result := True;
end
else
ErrText := SysErrorMessage(GetLastError);
finally
FreeAndNil(Stream);
end;
end
else
ErrText := SysErrorMessage(GetLastError);
except
ErrText := SysErrorMessage(GetLastError);
end;
finally
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG);
end;
finally
Free;
end;
end;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question