
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.220] |
![]() |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Подскажите пожалуйста кто сталкивался, если необходимо шифрование алгоритмом AES с помощью CryptoAPI, где именно нужно указывать, что шифрование будет именно этим алгоритмом (необходимо определенный криптопровайдер или определенный тип?)
![]() ![]() CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) Заранее очень благодарен! |
![]() |
Сообщ.
#2
,
|
|
насколько я помню то по умолчанию в винде нет провайдера который работает с AES
|
Сообщ.
#3
,
|
|
|
Цитата mawa @ где именно нужно указывать, что шифрование будет именно этим алгоритмом (необходимо определенный криптопровайдер или определенный тип?) Конкретный алгоритм указывается при создании ключа шифрования, а в CryptAcquireContext нужно указывать имя\тип провайдера, поддерживающего данный алгоритм. Судя по мсдн, AES поддерживается в WinXP и выше провайдером: тип = PROV_RSA_AES, имя = MS_ENH_RSA_AES_PROV |
Сообщ.
#4
,
|
|
|
Спасибо!
Добавлено Я обращаюсь через библиотеку wcrypt2.pas, но в ней нет - PROV_RSA_AES, имеется PROV_RSA_FULL и др. Что делать? |
Сообщ.
#5
,
|
|
|
Объяви сам эту константу. Она равна 24
|
Сообщ.
#6
,
|
|
|
![]() ![]() public { Public declarations } hProv: HCRYPTPROV; key: HCRYPTKEY; encrypt: boolean; end; .... var hProv: HCRYPTPROV; hash: HCRYPTHASH; key: HCRYPTKEY; data: PByte; l: DWORD; fl:boolean; i:integer; err,login,cript_rez: string; cript_temp_1:array[0..65535] of char; cript_temp_2:string[255]; Const PROV_RSA_AES=24; .... {получаем контекст криптопровайдера} CryptAcquireContext(@hProv, nil, nil, PROV_RSA_AES, 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); {выделяем место для буфера} GetMem(data, 512); {шифруем данные} login:=text; //данные fl:=true; l:=length(login); for i:=1 to length(login) do begin data^:=ord(login[i]); CryptEncrypt(key, 0, fl, 0, data, @l, l); cript_temp_1[i]:=chr(data^); cript_temp_2[i]:=cript_temp_1[i]; login[i]:=cript_temp_2[i]; //рез-т шифрования end; {освобождаем место и закрываем файлы} FreeMem(data, 512); {освобождаем контекст криптопровайдера} CryptReleaseContext(hProv, 0); Данный код реализован был для шифра RC4, а как для AES сделать? ![]() Добавлено Необходимо указать алгоритм - AES или CALG_AES, а там нет что делать? ![]() ![]() CryptDeriveKey(hProv, CALG_RC4, hash, 0, @key) |
Сообщ.
#7
,
|
|
|
Цитата mawa @ а там нет что делать? Прогуляться по MSDN. Тебе выше ссылку дали. Вот я кликаю по ней, в ней есть еще одна, которая ведет сюда: http://msdn.microsoft.com/en-us/library/aa375545(VS.85).aspx Теперь твоя очередь покликать ![]() ЗЫ: Если снова константа не будет объявлена - объявляй сам. Значение узнать можно в гугле. По запросу "define+имя_константы" находится код, по которому значение и узнается. |
Сообщ.
#9
,
|
|
|
Спасибо!
А вот когда зашифровываю текст, то выдается ошибка 'Unknown error', в чем может быть причина? ![]() ![]() {получаем контекст криптопровайдера} CryptAcquireContext(@hProv, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); {создаем хеш-объект} CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash); {хешируем пароль} CryptHashData(hash, @password[1], length(password), 0); {создаем ключ на основании пароля для AES_256} CryptDeriveKey(hProv,CALG_AES_256,hash,0,@key); .. {выделяем место для буфера} GetMem(data, 512); {шифруем данные} login:=text; //данные fl:=true; l:=length(login); for i:=1 to length(login) do begin data^:=ord(login[i]); if not CryptEncrypt(key, 0, fl, 0, data, @l, l) then begin case int64(GetLastError) of ERROR_INVALID_HANDLE: err := 'ERROR_INVALID_HANDLE'; ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; NTE_BAD_ALGID: err := 'NTE_BAD_ALGID'; NTE_BAD_DATA: err := 'NTE_BAD_DATA'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_HASH: err := 'NTE_BAD_HASH'; NTE_BAD_HASH_STATE: err := 'NTE_BAD_HASH_STATE'; NTE_BAD_KEY: err := 'NTE_BAD_KEY'; NTE_BAD_LEN: err := 'NTE_BAD_LEN'; NTE_BAD_UID: err := 'NTE_BAD_UID'; NTE_DOUBLE_ENCRYPT: err := 'NTE_DOUBLE_ENCRYPT'; NTE_FAIL: err := 'NTE_FAIL'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; else err := 'Unknown error'; // <-- выдается данное сообщение end; MessageDlg('Error of CryptEncrypt: '+err, mtError, [mbOK], 0); exit; end; cript_temp_1[i]:=chr(data^); cript_temp_2[i]:=cript_temp_1[i]; login[i]:=cript_temp_2[i]; //рез-т шифрования |
Сообщ.
#10
,
|
|
|
Попробуй получить описание ошибки через FormatMessage
![]() ![]() var e:cardinal; mbuf:array[0..511] of char; begin ... e:=GetLastError; case e of ... else begin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,e,0,mbuf,sizeof(mbuf),nil); err:=IntToStr(e)+#13#10+mbuf; end; |
Сообщ.
#11
,
|
|
|
![]() ![]() else err := 'Unknown error'; заменить на ![]() ![]() else RaiseLastOSError; |
Сообщ.
#12
,
|
|
|
ERROR CRYPTENCRYPT -- Unknown error
Добавлено CodeMonkey System Error. Code:234. Имеются дополнительные данные. Process stopped/ Use step or run to continue/ Добавлено leo Error of CryptEncrypt : 21 Устройство не готово |
Сообщ.
#13
,
|
|
|
Цитата mawa @ Имеются дополнительные данные. Значит 512 - мало. Добавлено По идее, надо как-то так: ![]() ![]() var login: String; X, Y: Integer; ... // вход: login - данные для шифрования // Шаг 1: определяем, сколько надо байт для хранения зашифрованного текста X := Length(login); if not CryptEncrypt(key, 0, True, 0, Pointer(login), X, Length(login)) then if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError; // Шаг 2: выделили буфер (уже не 512, а ровно, сколько надо) Y := Length(login); SetLength(login, X); // Шаг 3: шифрование if not CryptEncrypt(key, 0, True, 0, Pointer(login), Y, Length(login)) then RaiseLastOSError; SetLength(login, Y); // выход: login - зашифрованные данные Писал на коленке, могут быть описки. |
Сообщ.
#14
,
|
|
|
Шифрование вроде работает, по крайней мере получается билиберда, но нужно было :
![]() ![]() if not CryptEncrypt(key, 0, True, 0, Pointer(login), @X, Length(login)) then //@X А вот на расшифровывание ругается, пишит плохие данные : ![]() ![]() login:=z_text; X := Length(login); if not CryptDecrypt(key, 0, True, 0, Pointer(login), @X) then if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError; Y := Length(login); SetLength(login, X); if not CryptDecrypt(key, 0, True, 0, Pointer(login), @Y) then RaiseLastOSError; SetLength(login, Y); |
Сообщ.
#15
,
|
|
|
А дешифровка делается в один шаг. Не надо узнавать размер буфера: исходный текст всегда меньше размером. А вы в своём коде просто откусили от зашифрованного текста кусок и удивляетесь, а чего ж это он ругается на неполные данные.
|