| ||||
| ||||
Выполняю код: function TCrypter.Sign(data: TStream; rslt: TStream; alg_id: dword): boolean; var hHash: HCRYPTHASH; hExchKey: HCRYPTKEY; cbHash, dwBufferLen, dwSigLen: DWORD; pbHash, pbBuffer, pbSignature: Pointer; s: pchar; begin result := false; try //--- Создание объекта функции хеширования. if not CryptCreateHash(CryptContext.Provider, alg_id, 0, 0, @hHash) then raise TCryptException.Create(ceOtherCryptError);//Exception.Create('Hash object was NOT created '+INtToStr(getlasterror)); s := stralloc(5000); cbHash := 0; //--- Определение размера BLOBа и распределение памяти. if not CryptGetHashParam(hHash, HP_OID, nil, @cbHash, 0) then begin FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, nil, getlasterror, 0, @s, 0, nil); raise Exception.Create('Error computing BLOB length '+s); end; try GetMem(pbHash, cbHash); except raise Exception.Create('Memory was NOT allocated'); end; //--- Заполняем буфер и заносим его длину dwBufferLen := data.Size - data.Position; GetMem(pbBuffer, dwBufferLen); data.ReadBuffer(pbBuffer^, dwBufferLen); if not(CryptGetHashParam(hHash, HP_OID, pbHash, @cbHash, 0)) then raise TCryptException.Create(ceOtherCryptError); //--- Вычисление криптографического хеша буфера. if not CryptHashData(hHash, pbBuffer, dwBufferLen, 0) then raise Exception.Create('Error during CryptHashData'); //if not CryptGetUserKey(CryptContext.Provider,AT_KEYEXCHANGE, @hExchKey) then // raise TCryptException.Create(ceOtherCryptError); //--- Определение размера подписи и распределение памяти. dwSigLen := 0; if not CryptSignHash(hHash, AT_KEYEXCHANGE, nil, 0, nil, @dwSigLen) then begin raise Exception.Create('Size of sign was NOT determined, error='+inttostr(getlasterror)); end; //--- Распределение памяти под буфер подписи. GetMem(pbSignature, dwSigLen); //--- Подпись объекта функции хеширования. if not CryptSignHash(hHash, AT_KEYEXCHANGE, nil, 0, pbSignature, @dwSigLen) then //******** ТУТ ВЫПАДАЕТ С ОШИБКОЙ Key Does Not Exist. raise TCryptException.Create(ceOtherCryptError); //--- Запись результата в поток rslt.WriteBuffer(pbSignature^, dwSigLen); Result := true; finally //--- Уничтожение объекта функции хеширования. if hHash <> 0 then CryptDestroyHash(hHash); //--- Освобождение памяти FreeMem(pbSignature); FreeMem(pbBuffer); FreeMem(pbHash); end; end; Имя контейнера передаю в дружественном формате. Если передаю уникальное имя, валится на CryptAcquireContext. Вызов делается так: //--- create key container if not CryptAcquireContext(@hProv,pszContainerName,pszProviderName,dwProviderType, 0) then if not CryptAcquireContext(@hProv,pszContainerName,pszProviderName,dwProviderType, CRYPT_NEWKEYSET) then raise TCryptException.Create(ceCryptContextNotAcquired); параметры 'FAT12\34743A3F\RaUser-9.000\AC083', CP_GR3410_2001_PROV_A,PROV_GOST_2001_DH | ||||
Ответы: | ||||
| ||||
Если передаю уникальное имя контейнера, CryptAcquireContext выдает ошибку Keyset as registered is Invalid. Если передаю дружественное имя контейнера, ошибка возникает при вызове CryptSignHash - Key does not exist. Вызов CryptGetUserKey вываливается с ошибкой Key does not exist. Почему? Весь мозг сломал. Единственное, что приходит в голову - повреждение контейнера или дисковода | ||||
| ||||
попробуйте с ключом в реестре | ||||
| ||||
Дело в том, что если я создаю контейнер сам, то все работает ок. проблема только с ключевой дискетой, сгенерированной для меня центром сертификации | ||||
| ||||
В контейнере может не быть ключа AT_KEYEXCHANGE. Вместо него может быть AT_SIGNATURE. | ||||
| ||||
Спасибо, проверялись оба типа ключей. Впрочем, вопрос решен. Попросил сделать еще одну дискету, с ней все ок. Видимо, дискеты запорол. | ||||