Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.10;
Скачать: CL | DM;

Вниз

Access Violation при вызове CryptSignAndEncryptMessage   Найти похожие ветки 

 
DmitrySukach ©   (2006-07-27 14:58) [0]

Подскажите, что я делаю неправильно?
Вот полностью код после получения pCertContext:
const
CERT_ENCODING_TYPE = X509_ASN_ENCODING or PKCS_7_ASN_ENCODING;
var
pCertContext: PCCERT_CONTEXT;
SignPara: CRYPT_SIGN_MESSAGE_PARA;
EncryptPara: CRYPT_ENCRYPT_MESSAGE_PARA;
pbSignedAndEncryptedBlob: PBYTE;
dwKeySpec: DWORD;
hCryptProv: HCRYPTPROV;
bToBeSignedAndEncrypted: array[0..1] of BYTE;
cbToBeSignedAndEncrypted: DWORD;
cbSignedAndEncryptedBlob: DWORD;
begin
CryptAcquireCertificatePrivateKey(
pCertContext,
0,
nil,
@hCryptProv,
@dwKeySpec,
nil);

FillChar(SignPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA), 0);
SignPara.cbSize := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType := CERT_ENCODING_TYPE;
SignPara.pSigningCert := pCertContext;
SignPara.HashAlgorithm.pszObjId := szOID_RSA_MD2;
SignPara.cMsgCert := 1;
SignPara.rgpMsgCert := @pCertContext;

FillChar(EncryptPara, SizeOf(CRYPT_SIGN_MESSAGE_PARA), 0);
EncryptPara.cbSize := SizeOf(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType := CERT_ENCODING_TYPE;
EncryptPara.ContentEncryptionAlgorithm.pszObjId := szOID_RSA_RC4;
EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData := 0;
EncryptPara.pvEncryptionAuxInfo := nil;
EncryptPara.dwFlags := 0;
EncryptPara.dwInnerContentType := 0;

cbToBeSignedAndEncrypted := 1;
bToBeSignedAndEncrypted[0] := 33;
bToBeSignedAndEncrypted[1] := 44;
cbSignedAndEncryptedBlob := 0;
pbSignedAndEncryptedBlob := nil;

CryptSignAndEncryptMessage(
@SignPara,
@EncryptPara,
1,
pCertContext,
@bToBeSignedAndEncrypted,
cbToBeSignedAndEncrypted,
nil,
@cbSignedAndEncryptedBlob);
...

На этом вызове и вылетает.


 
Сергей М. ©   (2006-07-27 15:13) [1]


> что я делаю неправильно?


Как минимум одно - не выделяешь память под CCERT_CONTEXT


 
Reindeer Moss Eater ©   (2006-07-27 15:17) [2]

Нарисуй сюда свой прототип CryptSignAndEncryptMessage


 
DmitrySukach ©   (2006-07-27 15:18) [3]

Я же написал: "Вот полностью код после получения pCertContext". Сертификат я получил нормально:

 pCertContext := CertFindCertificateInStore(hStore, CERT_ENCODING_TYPE, 0,
   CERT_FIND_ANY, nil, nil);

 CertNameToStr(CERT_ENCODING_TYPE, @(pCertCtx^.pCertInfo^.Subject),
   CERT_SIMPLE_NAME_STR, szName, MAXBUFF);
 ShowMessage("Subject: " + szName);

Это всё работает, субъект показывает.


 
DmitrySukach ©   (2006-07-27 15:19) [4]

function CryptSignAndEncryptMessage(pSignPara :PCRYPT_SIGN_MESSAGE_PARA;
                                   pEncryptPara :PCRYPT_ENCRYPT_MESSAGE_PARA;
                                   cRecipientCert :DWORD;
                                   rgpRecipientCert :array of PCCERT_CONTEXT;
                             const pbToBeSignedAndEncrypted :PBYTE;
                                   cbToBeSignedAndEncrypted :DWORD;
                                   pbSignedAndEncryptedBlob :PBYTE;
                                   pcbSignedAndEncryptedBlob :PDWORD
                                   ):BOOL ; stdcall;


 
Reindeer Moss Eater ©   (2006-07-27 15:20) [5]

Засада вот здесь :

rgpRecipientCert :array of PCCERT_CONTEXT;


 
DmitrySukach ©   (2006-07-27 15:24) [6]

Я делал и так:

 cRecipientCert: DWORD;
 rgpRecipientCert: array[0..4] of PCCERT_CONTEXT;

 cRecipientCert := 1;
 rgpRecipientCert[0] := pCertContext;

 CryptSignAndEncryptMessage(
     @SignPara,
     @EncryptPara,
     cRecipientCert,
     rgpRecipientCert,
     @bToBeSignedAndEncrypted,
     cbToBeSignedAndEncrypted,
     nil,
     @cbSignedAndEncryptedBlob);

Тот же результат...


 
DmitrySukach ©   (2006-07-27 15:27) [7]

На Visual C++ это работает:

СryptAcquireCertificatePrivateKey(
       pSignerCertContext,
       0,
       NULL,
       &hCryptProv,
       &dwKeySpec,
       NULL);

   SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
   SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
   SignPara.pSigningCert = pSignerCertContext ;
   SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
   SignPara.HashAlgorithm.Parameters.cbData = 0;
   SignPara.pvHashAuxInfo = NULL;
   SignPara.cMsgCert = 1;
   SignPara.rgpMsgCert = &pSignerCertContext ;
   SignPara.cMsgCrl = 0;
   SignPara.rgpMsgCrl = NULL;
   SignPara.cAuthAttr = 0;
   SignPara.rgAuthAttr = NULL;
   SignPara.cUnauthAttr = 0;
   SignPara.rgUnauthAttr = NULL;
   SignPara.dwFlags = 0;
   SignPara.dwInnerContentType = 0;

   EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
   EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE;
   EncryptPara.hCryptProv = 0;
   EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4;
   EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
   EncryptPara.pvEncryptionAuxInfo = NULL;
   EncryptPara.dwFlags = 0;
   EncryptPara.dwInnerContentType = 0;

   cRecipientCert = 1;
   rgpRecipientCert[0] = pSignerCertContext;
   *pcbSignedAndEncryptedBlob = 0;
   pbSignedAndEncryptedBlob = NULL;

   CryptSignAndEncryptMessage(
       &SignPara,
       &EncryptPara,
       cRecipientCert,
       rgpRecipientCert,
       pbToBeSignedAndEncrypted,
       cbToBeSignedAndEncrypted,
       NULL,
       pcbSignedAndEncryptedBlob)


 
Reindeer Moss Eater ©   (2006-07-27 15:28) [8]

Про декларацию я уже говорил. Это одна из причин.
На джедаях выложена кривая трансяция Wincrypt2.h
Исходные параметры типа таких PCCERT_CONTEXT rgpRecipientCert[] везде заменены открытыми массивами Delphi. Но там совсем другая физическая организация.

Дальше надо искать ошибку в заполнении структур.


 
Reindeer Moss Eater ©   (2006-07-27 15:33) [9]

Вот моя переделка одной из деклараций

function CryptEncryptMessageMy(pEncryptPara          : PCRYPT_ENCRYPT_MESSAGE_PARA;
                              cRecipientCert        : DWORD;
                              rgpRecipientCert      : PCCERT_CONTEXT; //array of PCCERT_CONTEXT;
                              const pbToBeEncrypted : PBYTE;
                              cbToBeEncrypted       : DWORD;
                              pbEncryptedBlob       : PBYTE;
                              pcbEncryptedBlob      : PDWORD) : BOOL; stdcall;

То есть я использую просто скалярный параметр PCCERT_CONTEXT.
Если получателей больше одного, я "руками" распределяю память под несколько указателей и руками же рассовываю туда все PCCERT_CONTEXT.
А в качестве параметра идет первый из них.


 
DmitrySukach ©   (2006-07-27 15:46) [10]

Заменил прототип. Теперь вызов возвращает False и GetLastError даёт E_INVALIDARG...


 
DmitrySukach ©   (2006-07-27 15:56) [11]

Reindeer Moss Eater,
Вы не могли написать какой-нибудь работающий пример с CryptSignAndEncryptMessage?


 
Reindeer Moss Eater ©   (2006-07-27 16:14) [12]

>Теперь вызов возвращает False и GetLastError даёт E_INVALIDARG...

Остается побороть заполнение параметров.
Примера с CryptSignAndEncryptMessage нет.
Только по отдельности.


 
DmitrySukach ©   (2006-07-27 17:17) [13]

А рабютающий пример с CryptSignMessage есть?


 
Reindeer Moss Eater ©   (2006-07-27 18:00) [14]

procedure SignMessage(const AFileIn, AFileOut: string);
var
SignParams     : CRYPT_SIGN_MESSAGE_PARA;
pAuthorCert    : PCCERT_CONTEXT;
hStoreHandle   : HCERTSTORE;
hProv             : HCRYPTPROV;
bDetached      : boolean;
dwToBeSigned   : DWORD;
pbToBeSigned   : PBYTE;
dwSigned       : DWORD;
pbSigned       : PBYTE;
pbDummyArray   : Pointer;
cbDummyElem    : PByte;
cbDummyArray   : Pointer;
begin
bDetached := False;
get_file_data(AFileIn,dwToBeSigned,pbToBeSigned);
pbDummyArray   := @pbToBeSigned;
cbDummyArray   := @dwToBeSigned;
hStoreHandle   := CertOpenSystemStore(hProv,"MY");
if hStoreHandle = nil then Exit;
pAuthorCert := GetCertificateByTypeAndName("ИмяВладельца",hStoreHandle,AT_SIGNATURE); //пользовательская ф-ция, возвращающая сертификат по имени владельца
if pAuthorCert = nil then Exit;
ZeroMemory(@SignParams,SizeOf(CRYPT_SIGN_MESSAGE_PARA));
SignParams.cbSize                   := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
SignParams.dwMsgEncodingType        := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
SignParams.pSigningCert             := pAuthorCert;
SignParams.HashAlgorithm.pszObjId   := szOID_CP_GOST_R3411;// szOID_RSA_MD5;
SignParams.HashAlgorithm.Parameters.cbData := 0;
SignParams.cMsgCert                 := 0;
SignParams.rgpMsgCert               := nil;
SignParams.cAuthAttr                := 0;
SignParams.dwInnerContentType       := 0;
SignParams.cMsgCrl                  := 0;
SignParams.cUnauthAttr              := 0;
SignParams.dwFlags                  := 0;
if not CryptSignMessage(@SignParams,bDetached,1,pbDummyArray,cbDummyArray,nil,@dwSigned ) then Exit;
GetMem(pbSigned,dwSigned);
if CryptSignMessage(@SignParams,bDetached,1,pbDummyArray,cbDummyArray,pbSigned,@dwS igned) then
 SaveDataToFile(AFileOut,pbSigned^,dwSigned);
FreeMem(pbToBeSigned,dwToBeSigned);
FreeMem(pbSigned,dwSigned);
CertFreeCertificateContext(pAuthorCert);
CertCloseStore(hStoreHandle,0);
end;



Страницы: 1 вся ветка

Текущий архив: 2006.12.10;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.032 c
15-1163535427
Kerk
2006-11-14 23:17
2006.12.10
100 000чное скачивание


2-1164310772
Kostafey
2006-11-23 22:39
2006.12.10
Экспорт из TBDGridEh в Excel


2-1164014010
One_More_Slon
2006-11-20 12:13
2006.12.10
что то не уничтожилось :(


3-1160041068
Kolan
2006-10-05 13:37
2006.12.10
Проектирование иерархической БД.


3-1159868962
DimonS
2006-10-03 13:49
2006.12.10
Неправильный пароль в Access