2010-04-12 17 views
9

Czy ktoś może polecić bezpieczną kryptograficznie bibliotekę generatorów liczb pseudolosowych dla Delphi (Win32)?Czy istnieją jakieś kryptograficznie bezpieczne biblioteki PRNG dla Delphi?

Może być bezpłatny lub komercyjny, ale najlepiej będzie aktywny. Chciałbym, żeby zawierał kod źródłowy.

+0

Sprawdź http://blog.synopse.info/post/AES-CSPRNG - jest to silnie oparty na AES-256, kryptograficznie bezpieczny generator liczb pseudolosowych, o wyższym poziomie bezpieczeństwa niż czarna skrzynka CryptoAPI (wykorzystuje tylko CryptGenRandom jako źródło entropii). –

Odpowiedz

8

Można użyć Windows CryptoAPI:

uses Wcrypt2; 

function GenerateRandom(Len: Cardinal): TBytes; 
var 
    hProv : HCRYPTPROV; 
begin 
    if not CryptAcquireContext(@hProv, 
          nil, 
          MS_ENHANCED_PROV, 
          PROV_RSA_FULL, 
          CRYPT_VERIFYCONTEXT) then 
    CryptAcquireContext(@hProv, 
         nil, 
         MS_ENHANCED_PROV, 
         PROV_RSA_FULL, 
         CRYPT_NEWKEYSET + CRYPT_VERIFYCONTEXT); 

    if hProv > 0 then 
    try 
    SetLength(Result,Len); 
    CryptGenRandom(hProv,Len,@Result[0]); 
    finally 
    CryptReleaseContext(hProv,0); 
    end; 
end; 

przykładem zastosowania powyższy kod:

function BytesToHex(const Bytes: TBytes): string; 
var 
    i : integer; 
begin 
    for i := 0 to Length(Bytes)-1 do 
    Result := Result + IntToHex(Bytes[i],2); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowMessage(BytesToHex(GenerateRandom(16))); 
end; 
+2

Drugi CryptAcquireContext powinien być wykonany tylko wtedy, gdy GetLastError = NTE_BAD_KEYSET. W przeciwnym razie kod powinien wywołać wyjątek (RaiseLastOSError) lub zwrócić pustą tablicę. Źródło MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx –

+0

CryptGenRandom ma znane słabości. Zobacz http://eprint.iacr.org/2007/419.pdf Rozważ użycie go jako źródła entropii sprawdzonego CSPRNG, np. jako http://blog.synopse.info/post/AES-CSPRNG –

0

OpenSSL byłby możliwy. Źródło jest dostępne, chociaż nie jestem świadomy, czy dostępna jest wersja Delphi. Zawiera cryptographically secure prng. Jest to aktywny projekt, ale może być przesadą dla tego, czego szukasz.

5

Delphi Encryption Compendium (który słynie-owski w mówiąc społeczności Delphi niemieckim, ale nigdzie indziej - prawdopodobnie od oficjalnego promowania) zawiera kryptograficznie bezpieczne Yarrow RNG.

Właśnie to urządzenie DECRandom (a może DECUtils) i używać go w ten sposób (w tym przykładzie użyto IInteger ale nie jest to obowiązkowe):

function generateRandomNumber: IInteger; 
var 
    A: IInteger; 
begin 
    NRnd(A, 512); // generate 512 Bit random number, 2^512 <= A < 2^513 
    Result := A; 
end; 

initialization 
    // Method 1: uses system timer to initialize the RNG (seed) 
    RandomSeed; 
    // Method 2: use own seed 
    randomSeed(Data, SizeOf(Data)); 
+0

To przeskakuje nad losowym generowaniem nasion, co jest dużym problemem samo w sobie. Można użyć CryptoAPI (jak pokazano w innych odpowiedziach), aby wygenerować ziarno, a następnie DEC, aby wygenerować losowe. – gabr

+0

@gabr: Generowanie nasion jest oczywiście problemem - ale Dommer nie prosił o to. Jeśli karmisz Delphi PRNG dobrym nasieniem, nadal nie jest on uważany za bezpieczny pod względem kryptograficznym http: //en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator ... – Leo

+0

Zgadzam się, ale nadal należy podkreślić - szczególnie, że twój kod pokazuje dwa niezbyt dobre przykłady inicjowania nasion. – gabr

0

Byłem też zamiar zaproponować OpenSSL libraries. A także uwzględniasz szyfrowanie, SSL, mieszanie.
Indy przekonwertował wiele nagłówków i zawiera RAND_screen - ale to nie może/nie powinno być używane, oczywiście, w programach bez interfejsu użytkownika. Niestety brakuje większości RAND_ * - ale są one bardzo łatwe do zaimportowania i użycia.
np

function RAND_load_file(const filename: PAnsiChar; max_bytes: longint): integer; cdecl; external 'libeay32.dll'; 
function RAND_bytes(buf: PByte; num: integer): integer; cdecl; external 'libeay32.dll'; 
function RAND_pseudo_bytes(buf: PByte; num: integer): integer; cdecl; external 'libeay32.dll'; 

następnie w kodzie:

RAND_load_file(PAnsiChar(AnsiString('name-of-seed-file')), 512); 
    //or 
    //RAND_screen; 
    ... 
    ... 
    const 
    PKCS5_SALT_LEN = 8; 
    var 
    salt: TBytes; 
    begin 
    SetLength(salt, PKCS5_SALT_LEN); 
    RAND_pseudo_bytes(@salt[0], PKCS5_SALT_LEN); 
    ... 
    end; 

Te same kwestie omawiane nasion nadal obowiązują, oczywiście.

2

Sprawdź ISAAC (Indirect, Shift, Accumulate, Add i Count), szybki PRNG, a także kryptograficznie bezpieczne (burtleburtle.net/bob/rand/isaacafa.html). Prawdopodobnie ISAAC jest tak szybki jak słynny Mersenne Twister PRNG.

Wolfgang Ehrhardt zrobił port Pascal/Delphi for Izaak i jest dostępny w http://www.wolfgang-ehrhardt.de/misc_en.html#prng (bezpłatne i dostępne źródła). Istnieje również link do innego portu delphi na stronie autora, ale chciałbym iść z wersją "Wolfgang Ehrhardt". Znam jego stronę (http://www.wolfgang-ehrhardt.de/index.html) od wielu lat i od tego czasu aktualizuje on procedury pascal/delphi. Na pewno powinien to być ekspert!

Powiązane problemy