2013-01-02 48 views
0

如何在Delphi中使用此算法?德爾福有沒有一個類可以做到這一點?Delphi中的實現PBKDF2?

謝謝。

+1

請將您的意見發送至:[簡單文本文件加密基於密鑰](http://stackoverflow.com/questions/9482352/simple-text-file-encryption-based-on-a-key)如果你正在尋找一個用例。 – menjaraz

回答

2

我使用提供的鏈接@alzaimar和維基百科上的一些閱讀來實現算法。當然歡迎有待改進的建議!

type 
    TIdHMACClass = class of TIdHMAC; 

// Modeled after http://www.di-mgt.com.au/cryptoKDFs.html#PKCS5 
function PBKDF2(const P: TBytes; const S: TBytes; const C: Integer; 
    const kLen: Integer; PRFC: TIdHMACClass = nil): TBytes; 
var 
    PRF: TIdHMAC; 
    D: Integer; 
    I: Int32; 
    F: TBytes; 
    U: TBytes; 
    J: Integer; 
    T: TBytes; 

    function _ConcatenateBytes(const _B1: TBytes; const _B2: TBytes): TBytes; inline; 
    begin 
    SetLength(Result, Length(_B1) + Length(_B2)); 
    if Length(_B1) > 0 then 
     Move(_B1[Low(_B1)], Result[Low(Result)], Length(_B1)); 
    if Length(_B2) > 0 then 
     Move(_B2[Low(_B2)], Result[Low(Result)+Length(_B1)], Length(_B2)); 
    end; 

    function _INT_32_BE(const _I: Int32): TBytes; inline; 
    begin 
    Result := TBytes.Create(_I shr 24, _I shr 16, _I shr 8, _I); 
    end; 

    procedure _XorBytes(var _B1: TBytes; const _B2: TBytes); inline; 
    var 
    _I: Integer; 
    begin 
    for _I := Low(_B1) to High(_B1) do 
     _B1[_I] := _B1[_I] xor _B2[_I]; 
    end; 

begin 
    if not Assigned(PRFC) then 
    PRFC := TIdHMACSHA1; 

    PRF := PRFC.Create; 
    try 
    D := Ceil(kLen/PRF.HashSize); 
    PRF.Key := P; 
    for I := 1 to D do 
    begin 
     F := PRF.HashValue(_ConcatenateBytes(S, _INT_32_BE(I))); 
     U := Copy(F); 
     for J := 2 to C do 
     begin 
     U := PRF.HashValue(U); 
     _XorBytes(F, U); 
     end; 
     T := _ConcatenateBytes(T, F); 
    end; 
    Result := Copy(T, Low(T), kLen); 
    finally 
    PRF.Free; 
    end; 
end; 

procedure TestPBKDF2SHA1HMAC; 
var 
    P: TBytes; 
    S: TBytes; 
    K: TBytes; 

    function _BytesToHexString(const _B: TBytes): string; 
    var 
    _I: Integer; 
    begin 
    for _I := Low(_B) to High(_B) do 
     Result := Result + IntToHex(_B[_I], 2); 
    end; 

begin 
    P := TBytes.Create($70, $61, $73, $73, $77, $6F, $72, $64); 
    S := TBytes.Create($78, $57, $8E, $5A, $5D, $63, $CB, $06); 

    K := PBKDF2(P, S, 2048, 24); 
    Assert('BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643' = _BytesToHexString(K)); 

    P := TBytes.Create($70, $61, $73, $73, $77, $6F, $72, $64); 
    S := TBytes.Create($73, $61, $6C, $74); 

    K := PBKDF2(P, S, 1, 20); 
    Assert('0C60C80F961F0E71F3A9B524AF6012062FE037A6' = _BytesToHexString(K)); 
    K := PBKDF2(P, S, 2, 20); 
    Assert('EA6C014DC72D6F8CCD1ED92ACE1D41F0D8DE8957' = _BytesToHexString(K)); 
    K := PBKDF2(P, S, 4096, 20); 
    Assert('4B007901B765489ABEAD49D926F721D065A429C1' = _BytesToHexString(K)); 
    K := PBKDF2(P, S, 16777216, 20); 
    Assert('EEFE3D61CD4DA4E4E9945B3D6BA2158C2634E984' = _BytesToHexString(K)); 

    P := TBytes.Create($70, $61, $73, $73, $77, $6F, $72, $64, $50, $41, 
    $53, $53, $57, $4F, $52, $44, $70, $61, $73, $73, $77, $6F, $72, $64); 
    S := TBytes.Create($73, $61, $6C, $74, $53, $41, $4C, $54, $73, $61, $6C, 
    $74, $53, $41, $4C, $54, $73, $61, $6C, $74, $53, $41, $4C, $54, $73, $61, 
    $6C, $74, $53, $41, $4C, $54, $73, $61, $6C, $74); 

    K := PBKDF2(P, S, 4096, 25); 
    Assert('3D2EEC4FE41C849B80C8D83662C0E44A8B291A964CF2F07038' = _BytesToHexString(K)); 
end; 

做任何你喜歡的事情,但使用它需要您自擔風險。

+0

@djdijkstra我拒絕你的編輯,因爲我錯過了你的評論,解釋了爲什麼需要改變。對不起。我現在做了所有必要的更改以防止發現範圍檢查問題。 –