| Шифрование с закрытым ключём |
|
| Написал Snowy | |
| 20.06.2008 | |
|
Рассмотрим пример классического шифрования с закрытым ключём. Данное шифрование считается ненадёжным, если пароль заложен в программу. Если пароль вводится пользователем, то стойкость зависит от сложности пароля. Данный пример создан для удобства хранения шифрованных данных в реестре или текстовых и ini файлах. То есть, шифрованные бинарные данные возвращаются в текстовом HEX виде. В представленом ниже коде всего две функции: function EncString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string; function DecString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string;Первая шифрует, вторая, соответственно, дешифрует. Первый параметр обязательный - это сами данные. Второй параметр необязательный - это пароль. Если не указан, используется внутренний фиксированный пароль (константа def). Третий параметр совсем необязательный - алгоритм шифрования. Всего два варианта - RC2 и RC4. Для шифрования паролей лучше использовать RC2, т.к. в RC4 видно, сколько байт зашифровано. Для всего остального можно использовать RC4 (по умолчанию), чтоб не добавлять лишнего мусора. Пример использования: procedure TForm1.Button1Click(Sender: TObject); begin Edit2.Text := EncString(Edit1.Text); Edit1.Text := ''; end; procedure TForm1.Button2Click(Sender: TObject); begin Edit1.Text := DecString(Edit2.Text); end;Далее сам код модуля. Код не использует других модулей (даже Windows). Построен на CryptoAPI функциях системы, поэтому практически не добавляет веса программе и может использоваться, как в VCL проектах, так и в проектах на чистом API. Шифрованные данные "подсаливаются" так, что одни и те же данные, зашифрованные дважды, дают разный результат, что практически исключает возможность подобрать ключ анализом, а не тупым брутфорсом. unit MiniCry; interface const CALG_RC4 = ((3 shl 13) or (4 shl 9) or 1); CALG_RC2 = ((3 shl 13) or (3 shl 9) or 2); def = 'WrSxnCNBpJ7Ko4[e",7Ty)a0ykP)62Ce[.bAA;SuOf4*{nagx4s,;5!eHU!v=p3z'; function EncString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string; {* зашифровать строку } function DecString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string; {* расшифровать строку } implementation const ADVAPI32 = 'advapi32.dll'; PROV_RSA_FULL = 1; CRYPT_VERIFYCONTEXT = $F0000000; CALG_SHA = ((4 shl 13) or 0 or 4); type HCRYPTPROV = Cardinal; HCRYPTKEY = Cardinal; ALG_ID = Cardinal; PHCRYPTPROV = ^HCRYPTPROV; PHCRYPTKEY = ^HCRYPTKEY; LPAWSTR = PWideChar; HCRYPTHASH = Cardinal; PHCRYPTHASH = ^HCRYPTHASH; function CryptReleaseContext(hProv:HCRYPTPROV;dwFlags:LongWord):LongBool;stdcall;external ADVAPI32 name 'CryptReleaseContext'; function CryptAcquireContext(Prov:PHCRYPTPROV;Container:LPAWSTR;Provider:LPAWSTR;ProvType:LongWord;Flags:LongWord):LongBool;stdcall;external ADVAPI32 name 'CryptAcquireContextW'; function CryptEncrypt(Key:HCRYPTKEY;Hash:HCRYPTHASH;Final:LongBool;Flags:LongWord;Data:PBYTE;Len:PLongWord;BufLen:LongWord):LongBool;stdcall;external ADVAPI32 name 'CryptEncrypt'; function CryptDecrypt(Key:HCRYPTKEY;Hash:HCRYPTHASH;Final:LongBool;Flags:LongWord;Data:PBYTE;Len:PLongWord):LongBool;stdcall;external ADVAPI32 name 'CryptDecrypt'; function CryptCreateHash(Prov:HCRYPTPROV;Algid:ALG_ID;Key:HCRYPTKEY;Flags:LongInt;Hash:PHCRYPTHASH):LongBool;stdcall;external ADVAPI32 name 'CryptCreateHash'; function CryptHashData(Hash:HCRYPTHASH;Data:PBYTE;DataLen :LongInt;Flags:LongInt):LongBool;stdcall;external ADVAPI32 name 'CryptHashData'; function CryptDeriveKey(Prov:HCRYPTPROV;Algid:ALG_ID;BaseData:HCRYPTHASH;Flags:LongInt;Key:PHCRYPTKEY) :LongBool;stdcall;external ADVAPI32 name 'CryptDeriveKey'; function CryptDestroyHash(hHash :HCRYPTHASH) :LongBool;stdcall;external ADVAPI32 name 'CryptDestroyHash'; function ByteToHex(b: byte): string; function GetChar(b: byte): char; begin if b < 10 then Result := chr(Ord('0') + b) else Result := chr(Ord('A') - 10 + b); end; begin Result := GetChar(b div 16) + GetChar(b mod 16); end; function StringToHex(const s: string): string; var i: integer; begin result := ''; for i := 1 to Length(s) do result := result + ByteToHex(ord(s[i])); end; function StrToIntDef(s: string; def: integer): integer; var i, c: integer; begin Val(s, i, c); if c = 0 then Result := i else Result := def; end; function HexToString(const s: string): string; var i: integer; begin result := ''; for i := 1 to Length(s) div 2 do try result := result + chr(StrToIntDef('$' + copy(s, i*2-1, 2), 32)); except result := result + '?'; end; end; procedure InitPass(pass: string; alg: LongWord; var hProv: HCRYPTPROV; var hSKey: HCRYPTKEY); var hash: HCRYPTHASH; begin CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash); CryptHashData(hash, @pass[1], length(pass), 0); CryptDeriveKey(hProv, alg, hash, 0, @hSKey); CryptDestroyHash(hash); end; function EncString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string; var p: PByte; sz: LongWord; hProv: HCRYPTPROV; hSKey: HCRYPTKEY; begin InitPass(pass, alg, hProv, hSKey); Insert(chr(Random(256)), s, 1); sz := Length(s); GetMem(p, sz + 8); move(s[1], p^, sz); if CryptEncrypt(hSKey, 0, true, 0, p, @sz, sz + 8) then begin SetLength(result, sz); move(p^, result[1], sz); result := StringToHex(result); end else result := s; FreeMem(p); CryptReleaseContext(hProv, 0); end; function DecString(s: string; pass: string = def; alg: Cardinal = CALG_RC4): string; var p: PByte; sz: LongWord; hProv: HCRYPTPROV; hSKey: HCRYPTKEY; begin InitPass(pass, alg, hProv, hSKey); s := HexToString(s); sz := Length(s); GetMem(p, sz); move(s[1], p^, sz); if CryptDecrypt(hSKey, 0, true, 0, p, @sz) then begin SetLength(result, sz); move(p^, result[1], sz); delete(result, 1, 1); end else result := s; FreeMem(p); CryptReleaseContext(hProv, 0); end; initialization Randomize; end. |
| След. > |
|---|


Благодарен за пример!!!
re: - [quote=Анонимно]У меня при запуске такая ошибка:_http://ra...
При запуске установки Delphi 2010, пишет что ему нужен Microsoft...
[url=http://www.isfarinka.ru][img]http://www.isfarinka.ru/e107_i...
re: - [quote=alexm]конечно подборочка супер - нечего сказать!Но...
комментарий к теме - Только тут мрамор Киев по приемлемой цене
Два предыдущих топика относятся к модераторам uNet.
Жду письма с правильным URL активации.
Ваша ошибка - Вы оправили не полный адрес активации:http://www.u...
Либо DelphiDistiller не работает, либо чего-то не понимаю, после...