Вверх ↑
Ответов: 5446
Рейтинг: 323
#1: 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