1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| unit PBKDF2Unit;
interface
const HASH_RIPEMD160 = 1;
HASH_SHA512 = 2;
uses DCPsha512, DCPripemd160, DCPcrypt2, Math;
function PBKDF2(pass, salt: ansistring; count, kLen: Integer; algorithm : byte): ansistring;
implementation
function PBKDF2(pass, salt: ansistring; count, kLen: Integer; algorithm : byte): ansistring;
var block_count, hashSizeBytes, i, j : integer;
xorsum, last : ansistring;
hashObject : TDCP_hash;
function XorBlock(s, x: ansistring): ansistring; inline;
var i: Integer;
begin
SetLength(Result, Length(s));
for i := 1 to Length(s) do Result[i] := Char(Byte(s[i]) xor Byte(x[i]));
end;
function RPad(x: ansistring; c: Char; s: Integer): ansistring; inline;
var i : Integer;
begin
Result := x;
if Length(x) < s then for i := 1 to s-Length(x) do Result := Result + c;
end;
function CalcDigest(text: ansistring): ansistring; inline;
begin
hashObject.Init;
hashObject.UpdateStr(text);
SetLength(Result, hashSizeBytes);
hashObject.Final(Result[1]);
end;
function HMAC(message, key : ansistring) : ansistring; inline;
const blocksize = 64;
begin
// Definition RFC 2104
if Length(key) > blocksize then key:= CalcDigest(key);
key := RPad(key, #0, blocksize);
Result := CalcDigest(XorBlock(key, RPad('', #$36, blocksize)) + message);
Result := CalcDigest(XorBlock(key, RPad('', #$5c, blocksize)) + result);
end;
function IntX(i: Integer): ansistring; inline;
begin
Result := Char(i shr 24) + Char(i shr 16) + Char(i shr 8) + Char(i);
end;
begin
result:= '';
case algorithm of
HASH_RIPEMD160 : hashObject:= TDCP_ripemd160.Create(nil);
HASH_SHA512 : hashObject:= TDCP_sha512.Create(nil);
end;
try
hashSizeBytes:= hashObject.GetHashSize div 8;
block_count:= ceil(kLen / hashSizeBytes);
for i:= 1 to block_count do
begin
last:= salt + IntX(i); // OK
// first iteration
last:= HMAC(last,pass); // OK
xorsum:= last;
// perform the other count - 1 iterations
for j:= 1 to (count-1) do
begin
last:= HMAC(last,pass);
xorsum:= XorBlock(xorsum,last);
end;
result:= result+xorsum;
end;
result:= copy(result,1,kLen);
finally
hashObject.free;
end;
end;
end. |
Partager