Delphi 是否有密码安全的PRNG库?[已关闭]

db2dz4w8  于 2023-01-08  发布在  其他
关注(0)|答案(6)|浏览(135)

要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于Stack Overflow来说是离题的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止已经采取了哪些措施来解决它。
八年前就关门了。
Improve this question
有人能推荐一个密码学上安全的Delphi(Win32)伪随机数生成器库吗?
可以免费或商业,但最好是一个积极的项目。我想它包括源代码。

qvsjd97n

qvsjd97n1#

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

wdebmtf22#

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

jgovgodb3#

看看ISAAC (Indirection, Shift, Accumulate, Add, and Count),一个快速的PRNG,也是密码学上安全的。也许ISAAC和著名的Mersenne Twister PRNG一样快。
Wolfgang Ehrhardt已经为ISAAC做了Pascal/ Delphi 移植(免费,源代码可用)。在作者的网站上也有一个到另一个Delphi移植的链接,但是我会选择“Wolfgang Ehrhardt”版本。我知道他的网站很多年了,从那时起他就一直在更新Pascal/Delphi例程。当然应该是这方面的Maven!

0g0grzrc

0g0grzrc4#

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

r8xiu3jd

r8xiu3jd5#

OpenSSL将是一个可能性。源代码是可用的,虽然我不知道如果 Delphi 版本是可用的。它包括一个cryptographically secure prng。这是一个活跃的项目,但它可能是矫枉过正,为您正在寻找的。

6mw9ycah

6mw9ycah6#

我还打算建议OpenSSL libraries。你还可以得到加密,ssl,哈希等包括在内。
Indy已经转换了很多头文件,并且包含了RAND_screen--但是显然,在没有UI的程序上不能/不应该使用RAND_screen。不幸的是,它遗漏了大部分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;

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

相关问题