Вверх ↑
Этот топик читают: Гость
Ответов: 5446
Рейтинг: 323
#1: 2011-01-28 13:19:56 ЛС | профиль | цитата
Было бы неплохо пополнить список методов компонента Crypt классическими методами вроде DES, 3-DES и т.д.. Взять код можно непосредственно из Windows, зовётся MS CryptoAPI, есть портированный под Delphi код: JEDI.
карма: 1

0
vip
#1.1контекстная реклама от партнеров
Ответов: 1841
Рейтинг: 369
#2: 2011-02-11 12:26:12 ЛС | профиль | цитата
iarspider писал(а):
вроде DES

да, не помешал бы он сейчас
карма: 1
0
Ответов: 839
Рейтинг: 17
#3: 2011-02-11 20:51:58 ЛС | профиль | цитата
тоже бы не отказался бы
карма: 0

0
Ответов: 5446
Рейтинг: 323
#4: 2011-02-13 00:29:44 ЛС | профиль | цитата
В надежде, что кто-нибудь таки доделает компонент, буду потихоньку выкладывать алгоритмы работы с CryptoAPI. Код на C++, ибо Delphi не знаю. Перевести на Delphi для знающего человека не составит труда.

Все функции CryptoAPI живут в advapi32.dll

== Шифрование данных ==

1. Создадим CryptoContext (т.е. зададим сборник алгоритмов шифрования):
CryptAcquireContext(  &hCryptProv, 
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
0)
Здесь hCryptProv - переменная типа HCRYPTPROV (unsigned long), MS_ENHANCED_PROV - строка (PChar) "Microsoft Enhanced Cryptographic Provider v1.0", PROV_RSA_FULL - константа, равная 1.

2. Создадим ключ на основе пароля (если быть точным, то на основе хеша пароля).
2а. Создаём контекст для вычисления хеша:
CryptCreateHash(   hCryptProv, 
CALG_MD5,
0,
0,
&hHash)
где hHash - переменная типа HCRYPTHASH (unsigned long), CALG_MD5 - константа, равная 0x00008003.
2б. Вычисляем хэш от пароля:
CryptHashData(   hHash, 
(BYTE *)pszPassword,
strlen(pszPassword),
0)
где pszPassword - ANSI строка (null-terminated), strlen - функция вычисления длины строки.
2в. Получаем ключ:
CryptDeriveKey(   hCryptProv, 
ENCRYPT_ALGORITHM,
hHash,
KEYLENGTH,
&hKey)
где ENCRYPT_ALGORITHM - выбранный алгоритм шифрования:
АлгоритмКонстантаЗначениеРазмер блокаРазмер ключа
DESCALG_DES0x000066016456
Triple DES с двумя ключамиCALG_3DES_1120x0000660964112
Triple DESCALG_3DES0x0000660364128
RC2CALG_RC20x0000660264128


а KEYLENGTH - это размер ключа, сдвинутый влево на 16.

3. Поблочно шифруем данные:
CryptEncrypt(   hKey, 
NULL,
fEOF,
0,
pbBuffer,
&dwCount,
dwBufferLen)
где fEOF - флаг "последний блок" (1 если этот блок последний, иначе 0), pbBuffer - блок данных для шифрования (общая длина - dwBufferLen, данных в нём dwCount байт, dwCount должно нацело делиться на размер блока, если fEOF = 0). После вызова в pbBuffer будут лежать dwCount байт зашифрованных данных.

4. Убираем за собой:
CryptDestroyHash(hHash); CryptDestroyKey(hKey); CryptReleaseContext(hCryptProv, 0);

== Дешифровка данных ==

Всё то же самое, только на третьем шаге вызывается функция
CryptDecrypt(              hKey, 
0,
fEOF,
0,
pbBuffer,
&dwCount)

== Прототипы использованных функций ==
WINADVAPI
BOOL
WINAPI
CryptAcquireContextA(
HCRYPTPROV *phProv,
LPCSTR szContainer,
LPCSTR szProvider,
DWORD dwProvType,
DWORD dwFlags
);

WINADVAPI
BOOL
WINAPI
CryptCreateHash(
__in HCRYPTPROV hProv,
__in ALG_ID Algid,
__in HCRYPTKEY hKey,
__in DWORD dwFlags,
__out HCRYPTHASH *phHash
);

WINADVAPI
BOOL
WINAPI
CryptHashData(
__in HCRYPTHASH hHash,
__in_bcount(dwDataLen) CONST BYTE *pbData,
__in DWORD dwDataLen,
__in DWORD dwFlags
);

WINADVAPI
BOOL
WINAPI
CryptDeriveKey(
__in HCRYPTPROV hProv,
__in ALG_ID Algid,
__in HCRYPTHASH hBaseData,
__in DWORD dwFlags,
__out HCRYPTKEY *phKey
);

WINADVAPI
__success(0 < return) BOOL
WINAPI
CryptEncrypt(
__in HCRYPTKEY hKey,
__in HCRYPTHASH hHash,
__in BOOL Final,
__in DWORD dwFlags,
__inout_bcount_part(dwBufLen, *pdwDataLen) BYTE *pbData,
__out DWORD *pdwDataLen,
__in DWORD dwBufLen
);

WINADVAPI
BOOL
WINAPI
CryptDecrypt(
__in HCRYPTKEY hKey,
__in HCRYPTHASH hHash,
__in BOOL Final,
__in DWORD dwFlags,
__inout_bcount_part(*pdwDataLen, *pdwDataLen) BYTE *pbData,
__deref_inout DWORD *pdwDataLen
);

WINADVAPIBOOL
WINAPI
CryptDestroyHash(
__in HCRYPTHASH hHash
);

WINADVAPI
BOOL
WINAPI
CryptDestroyKey(
__in HCRYPTKEY hKey
);

WINADVAPI
BOOL
WINAPI
CryptReleaseContext(
__in HCRYPTPROV hProv,
__in DWORD dwFlags
);

------------ Дoбавленo в 00.29:
Рассмотренные выше алгоритмы - симметричные. С асимметричными (RSA) пляска на порядок сложнее, и в концепцию компонента CRYPT уже не укладывается.

карма: 1

0
Ответов: 839
Рейтинг: 17
#5: 2011-02-13 07:31:33 ЛС | профиль | цитата
iarspider
Молодец!! дело за малым ,теперь ждём кто знает делфи и сделает
карма: 0

0
Ответов: 3349
Рейтинг: 233
#6: 2011-02-13 11:32:50 ЛС | профиль | цитата
Готов немного помоч
------------ Дoбавленo в 11.32:
Add(InlineCode,3931890,462,483)
{
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses kol,Share,Debug,windows;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|0:|5: end;|0:|22:HCRYPTPROV = Cardinal;|22:HCRYPTHASH = Cardinal;|22:HCRYPTKEY = Cardinal;|19:ALG_ID = DWORD;|0:|14:implementation|0:|176:function CryptAcquireContext(out phProv:HCRYPTPROV; pszContainer, pszProvider:PChar; dwProvType,dwFlags:dword):bool;stdcall; external 'Advapi32.dll' name 'CryptAcquireContext';|0:|172:function CryptCreateHash(hProv:HCRYPTPROV; Algid:ALG_ID; hKey:HCRYPTKEY ;dwFlags:DWORD;out phHash:HCRYPTHASH):bool; stdcall; external 'Advapi32.dll' name 'CryptCreateHash';|0:|140:function CryptHashData(hHash:HCRYPTHASH; pbData:pbyte; dwDataLen,dwFlags:DWORD):bool; stdcall; external 'Advapi32.dll' name 'CryptHashData';|0:|4:end.|
}

Экспорт функций
------------ Дoбавленo в 11.32:
Да и то не всех, вечером еще будут.
карма: 1

0
Ответов: 1528
Рейтинг: 57
#7: 2011-02-13 11:46:05 ЛС | профиль | цитата
iarspider писал(а):
3-DES

уже давно есть в виде отдельного компонента
карма: 0

0
Ответов: 1321
Рейтинг: 37
#8: 2011-02-13 12:02:09 ЛС | профиль | цитата
Где???
карма: 0

0
Ответов: 5446
Рейтинг: 323
#9: 2011-02-13 12:11:48 ЛС | профиль | цитата
Добавил прототипы использованных функций.
карма: 1

0
Ответов: 1528
Рейтинг: 57
#10: 2011-02-13 13:21:13 ЛС | профиль | цитата
Roma, http://hiasm.com/xf/attach/files/crypt.rar
карма: 0

0
Ответов: 5446
Рейтинг: 323
#11: 2011-02-13 13:36:31 ЛС | профиль | цитата
Поправил и дополнил код от Ivann-а:
code_22521.txt
карма: 1

0
файлы: 1code_22521.txt [1.8KB] [604]
Ответов: 3349
Рейтинг: 233
#12: 2011-02-13 15:39:49 ЛС | профиль | цитата
iarspider, а кто будет указывать тип результата функции?
------------ Дoбавленo в 15.39:
Add(InlineCode,3931890,399,434)
{
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses kol,Share,Debug,windows;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|0:|5: end;|1: |19:ULONG_PTR = DWORD;|20:PDWORD = ^DWORD;|23:HCRYPTPROV = ULONG_PTR;|25:PCRYPTPROV = ^HCRYPTPROV;|23:HCRYPTHASH = ULONG_PTR;|25:PCRYPTHASH = ^HCRYPTHASH;|23:HCRYPTKEY = ULONG_PTR;|24:PCRYPTKEY = ^HCRYPTKEY;|19:ALG_ID = DWORD;|0:|14:implementation|0:|177:function CryptAcquireContext(out phProv:PCRYPTPROV; pszContainer, pszProvider:PChar; dwProvType,dwFlags:dword):bool;stdcall; external 'Advapi32.dll' name 'CryptAcquireContextA';|172:function CryptCreateHash(hProv:HCRYPTPROV; Algid:ALG_ID; hKey:HCRYPTKEY ;dwFlags:DWORD;out phHash:PCRYPTHASH):bool; stdcall; external 'Advapi32.dll' name 'CryptCreateHash';|140:function CryptHashData(hHash:HCRYPTHASH; pbData:pbyte; dwDataLen,dwFlags:DWORD):bool; stdcall; external 'Advapi32.dll' name 'CryptHashData';|170:function CryptDeriveKey(hProv:HCRYPTPROV; Algid:ALG_ID; hBaseData:HCRYPTHASH; dwFlags:DWORD; phKey:PCRYPTKEY):bool;stdcall; external 'Advapi32.dll' name 'CryptDeriveKey';|191:function CryptEncrypt(hKey:HCRYPTKEY; hHash:HCRYPTHASH; Final_:BOOL; dwFlags:DWORD; pbData:pbyte; pdwDataLen:PDWORD; dwBufLen:DWORD):bool;stdcall; external 'Advapi32.dll' name 'CryptEncrypt';|175:function CryptDecrypt(hKey:HCRYPTKEY; hHash:HCRYPTHASH; Final_:BOOL; dwFlags:DWORD; pbData:pbyte; pdwDataLen:PDWORD):bool;stdcall; external 'Advapi32.dll' name 'CryptDecrypt';|106:function CryptDestroyHash(hHash:HCRYPTHASH):bool;stdcall; external 'Advapi32.dll' name 'CryptDestroyHash';|102:function CryptDestroyKey(hKey:HCRYPTKEY):bool;stdcall; external 'Advapi32.dll' name 'CryptDestroyKey';|127:function CryptReleaseContext(hProv:HCRYPTPROV; dwFlags:DWORD):bool;stdcall; external 'Advapi32.dll' name 'CryptReleaseContext';|0:|4:end.|
}


карма: 1

0
Ответов: 5446
Рейтинг: 323
#13: 2011-02-13 22:32:56 ЛС | профиль | цитата
Начал писать тело компонента. В тему призывается nesco как главный специалист по WinAPI для помощи с передачей и приёмом строк.
code_22530.txt
------------ Дoбавленo в 22.32:
Нашёл "рыбу" кода шифрования текста:
{«описание» используемых переменных}
hProv: HCRYPTPROV;
hash: HCRYPTHASH;
password: string;
key: HCRYPTKEY;
plaintext, ciphertext: string;
inFile, outFile: file;
data: PByte;
l: DWORD;

{получаем контекст криптопровайдера}
CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
{создаем хеш-объект}
CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash);
{хешируем пароль}
CryptHashData(hash, @password[1], length(password), 0);
{создаем ключ на основании пароля для потокового шифра RC4}
CryptDeriveKey(hProv, CALG_RC4, hash, 0, @key);
{уничтожаем хеш-объект}
CryptDestroyHash(hash);
{открываем файлы}
AssignFile(inFile, plaintext);
AssignFile(outFile, ciphertext);
reset(inFile, 1);
rewrite(outFile, 1);
{выделяем место для буфера}
GetMem(data, 512);
{шифруем данные}
while not eof(inFile) do
begin
BlockRead(inFile, data^, 512, l);
CryptEncrypt(key, 0, eof(inFile), 0, data, @l, l);
BlockWrite(outFile, data^, l);
end;
{освобождаем место и закрываем файлы}
FreeMem(data, 512);
CloseFile(inFile);
CloseFile(outFile);
{освобождаем контекст криптопровайдера}
CryptReleaseContext(hProv, 0);

nesco, помоги!
карма: 1

0
файлы: 1code_22530.txt [4.2KB] [571]
Разработчик
Ответов: 26071
Рейтинг: 2122
#14: 2011-02-13 22:47:19 ЛС | профиль | цитата
iarspider писал(а):
nesco, помоги!

А че конкретно надо
карма: 22

0
Ответов: 5446
Рейтинг: 323
#15: 2011-02-13 22:54:17 ЛС | профиль | цитата
nesco, в code_22530 загляни - надо места помеченные ??? заполнить кодом (см. первый пост плюс "рыбу"). Ну и заодно общий стиль посмотреть...
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)