Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Хэширование строк в SHA1 [D7]


ixen ©   (2013-09-30 18:47:00) 

Привет! Нужно получить хэш SHA1 текстовой строки. Погуглив нашел несколько примеров, и немного их переделав, у меня получилось вот что:

functionTForm1.crypthash(str:string; calc:Cardinal):string;
varhProv: HCRYPTPROV;
   hHash: HCRYPTHASH;
   pbHash: PByte;
   I:integer;
   BufLen:DWORD;
   buf,res:PChar;
begin
 result:='';
 if not CryptAcquireContext(@hProv,nil,nil,PROV_RSA_FULL, CRYPT_NEWKEYSET)
 then CryptAcquireContext(@hProv,nil,MS_ENHANCED_PROV,PROV_RSA_FULL, 0); // создаем контейнер

 CryptCreateHash(hProv, calc,0,0,@hHash); // подключаемся к провайдеру

 CryptHashData(hHash,PByte(PAnsiChar(str)),length(str),0); // получаем хэш строки
 buflen:=0;
 CryptGetHashParam(hHash, HP_HASHVAL, nil, @BufLen,0); // получаем размер буфера
 GetMem(pbHash, buflen); // выделяем память под хранение хэша в бинарном виде
 if CryptGetHashParam(hHash,HP_HASHVAL,pbHash, @BufLen,0) then // получаем хэш в бинарном виде
  begin
   buf:=PAnsiChar(pbhash); // представляю бинарный хэш в чар
   bintohex(buf, res, buflen); // перевожу бинарный хэш в шестнадцатиричный
   result:=res; // присваиваю результат функции
  end;
 FreeMem(pbHash);  // освобождаю память
 CryptDestroyHash(hHash); // уничтожаю хэш
 CryptReleaseContext(hProv, 0);  // отключаюсь от провайдера
end;


вызываю следующим образом:
sha1_edt.Text:=crypthash(sign_edt.Text,CALG_SHA1);

в результате выходит сообщение AV, но результат все таки вычисляется правильный, но только с мусором, например:
текст=123
хэш= 40BD001563085FC35165329EA1FF5C5ECBDBBEEFøˆC

жирным это правильный хэш, а в конце мусор. Хэш проверял через сайт http://www.sha1-online.com/

Подскажите как сделать без ошибок и без мусора. Знаю что где то с выделением памяти напортачил, но я в этом не силен.


ixen   (2013-10-03 23:39:00) [1]

DVM,  спасибо большое за модули. Вопросов не будет, там все понятно.


ProgRAMmer Dimonych   (2013-10-02 23:55:00) [2]

> [16] DVM ©   (02.10.13 22:50)

Сейчас посыплются вопросы по использованию модуля. А смысл?


DVM   (2013-10-02 22:50:00) [3]


> ixen   (02.10.13 19:15) [15]


> А этот модуль может считать хэш md5 ?

этот не может, вот этот может: http://yadi.sk/d/-_LkQxucAJ6dd


ixen   (2013-10-02 19:15:00) [4]


> Попробуй мой модуль: http://yadi.sk/d/PvxlW4D8AFVxH
> С ним попроще будет, да и кроссплатформенно.

Спасибо, попробую. А этот модуль может считать хэш md5 ?


Необычный порошок   (2013-10-02 13:35:00) [5]

это капец конечно.
работать с PChar через new и dispose.
какие еще рандомные комбинации функций ты можешь придумать?


ProgRAMmer Dimonych   (2013-10-02 12:17:00) [6]

> [11] ixen   (02.10.13 08:51)
> Немного подправил код, AV выходит при закрытии программы.
> Хэш считает правильно но в конце один знак псевдографики
> добавляется..
> function TForm1.crypthash(str:string; calc:Cardinal):string;
>
> var hProv: HCRYPTPROV;
>  hHash: HCRYPTHASH;
>  pbHash: PByte;
>  I:integer;
>  BufLen:DWORD;
>  buf,res:PChar;
> begin
> ...
> if CryptGetHashParam(hHash,HP_HASHVAL,pbHash, @BufLen,0)
> then // получаем хэш в бинарном виде
> begin
>  buf:=PChar(pbhash); // представляю бинарный хэш в чар
>  New(res);  // резервирую память под переменную res
>  bintohex(buf, res, buflen); // перевожу бинарный хэш в
> шестнадцатиричный
>  result:=res; // присваиваю результат функции
> Dispose(res);   // освобождаю память под переменную res
> end;
> ...
> end;

Ну ещё бы! Сколько по-твоему памяти выделит New(), сколько будет использовать таинственный bintohex() и что из всего этого получится?


DVM   (2013-10-02 10:27:00) [7]


> ixen

Попробуй мой модуль: http://yadi.sk/d/PvxlW4D8AFVxH
С ним попроще будет, да и кроссплатформенно.


ixen   (2013-10-02 08:51:00) [8]

Немного подправил код, AV выходит при закрытии программы. Хэш считает правильно но в конце один знак псевдографики добавляется..
function TForm1.crypthash(str:string; calc:Cardinal):string;
var hProv: HCRYPTPROV;
  hHash: HCRYPTHASH;
  pbHash: PByte;
  I:integer;
  BufLen:DWORD;
  buf,res:PChar;
begin
...
if CryptGetHashParam(hHash,HP_HASHVAL,pbHash, @BufLen,0) then // получаем хэш в бинарном виде
begin
  buf:=PChar(pbhash); // представляю бинарный хэш в чар
  New(res); // резервирую память под переменную res
  bintohex(buf, res, buflen); // перевожу бинарный хэш в шестнадцатиричный
  result:=res; // присваиваю результат функции
 Dispose(res);  // освобождаю память под переменную res
end;
...
end;


Необычный порошок   (2013-10-01 19:23:00) [9]

Типа Pchar

ну значит ковыряй свой странный бинтухекс, который хочет указатель на двоичный буфер в виде пчара


brother   (2013-10-01 16:57:00) [10]

это указатель на содержимое...


ixen   (2013-10-01 16:54:00) [11]


> какого типа параметр buf у bintohex?

Типа Pchar


Необычный порошок   (2013-10-01 11:53:00) [12]

bintohex(buf, res, buflen); // перевожу бинарный хэш в шестнадцатиричный

Видимо я не правильно его перевожу.

какого типа параметр buf у bintohex?


Inovet   (2013-10-01 11:37:00) [13]

> [5] ixen   (01.10.13 07:38)
> его нужно перевести в шестнадцатеричный код

Что это значит? Зачем во что-то переводить значение указателя?


ixen   (2013-10-01 07:38:00) [14]

Я посмотрел содержимое переменной хэша pbHash, выполняя код по шагам, там получается значение $1463F38. Я так понимаю его нужно перевести в шестнадцатеричный код. Видимо я не правильно его перевожу.


ixen   (2013-10-01 07:31:00) [15]

Я пробовал другой модуль jwaWinCrypt.. результат такой же


Необычный Порошок   (2013-09-30 20:00:00) [16]

кстати, если внутри wincrypt2.pas лежат копирайты мадам марии массимо гизалберти, то ее этот порт с в пас - кривой.

а еще полезно смотреть что за результат возвращают вызываемые функции и время от времени делать гетластеррор


Необычный Порошок   (2013-09-30 19:39:00) [17]

1. Убрать вот эту ересь.
if not CryptAcquireContext(@hProv,nil,nil,PROV_RSA_FULL, CRYPT_NEWKEYSET)

контейнер и его приват ключи нам не нужны, тем более не нужно генерить новый контейнер. флаг CRYPT_VERIFYCONTEXT

2. зачем здесь PAnsiChar?

 buf:=PAnsiChar(pbhash); // представляю бинарный хэш в чар
 bintohex(buf, res, buflen); // перевожу бинарный хэш в шестнадцатиричный

Остальные косяки зависят от того как объявлены параметры функций в твоем  wcrypt2.pas


ixen   (2013-09-30 18:51:00) [18]

Забыл добавить. Использую модуль wcrypt2.pas


Наверх

Титульная страница Поиск, карта сайта Написать письмо