Delphi有加密安全的PRNG库吗?

时间:2010-04-12 12:10:57

标签: delphi random

任何人都可以为Delphi(Win32)推荐一个加密安全的伪随机数生成器库吗?

可以是免费的或商业的,但理想情况下是一个活跃的项目。我希望它包含源代码。

6 个答案:

答案 0 :(得分:8)

您可以使用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;

使用上述代码的示例:

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;

答案 1 :(得分:5)

Delphi Encryption Compendium(在德语Delphi社区中很有名,但在其他任何地方 - 可能是因为它没有得到官方推广)包含加密安全Yarrow RNG

只需包含单元DECRandom(也许DECUtils)并像这样使用它(此示例使用IInteger但这不是必需的):

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));

答案 2 :(得分:2)

查看ISAAC(间接,转移,累积,添加和计数),快速PRNG以及加密安全(burtleburtle.net/bob/rand/isaacafa.html)。可能ISAAC和着名的Mersenne Twister PRNG一样快。

Wolfgang Ehrhardt为ISAAC完成了pascal / delphi端口,可以在 http://www.wolfgang-ehrhardt.de/misc_en.html#prng (免费和来源可用)。还有一个链接到作者网站上提供的另一个delphi端口,但我会选择“Wolfgang Ehrhardt”版本。我知道他的网站(http://www.wolfgang-ehrhardt.de/index.html)已经很多年了,从那以后他一直在用pascal / delphi例程进行更新。当然应该是这方面的专家!

答案 3 :(得分:1)

您可以使用现有的Win32 CryptGenRandom() API。

答案 4 :(得分:0)

OpenSSL是一种可能性。虽然我不知道Delphi版本是否可用,但是源代码可用。它包括cryptographically secure prng。这是一个活跃的项目,但对于您正在寻找的内容可能过度。

答案 5 :(得分:0)

我还要建议OpenSSL libraries。并且还包括加密,SSL,散列等 Indy已经转换了许多标题并包含RAND_screen - 但显然,它不能/不应该用于没有UI的程序。不幸的是,它错过了大多数RAND_ * - 但它们很容易导入和使用。
例如:

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';

然后在代码中:

  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;

当然,所讨论的种子问题仍然适用。