【问题标题】:delphi: generate random data for cryptographicdelphi:为密码生成随机数据
【发布时间】:2016-10-22 23:26:12
【问题描述】:

我需要为加密目的生成一个 12 字节的随机数据。我的第一个想法是使用类似的东西

random(maxint) * random(maxint) * random(maxint)

但我发现这在多线程上效率不高,因为随机使用全局变量 RandSeed(实际上随机不是多线程)。随机看起来也很容易猜到:

function Random(const ARange: Integer): Integer;
var
  Temp: Integer;
begin
  Temp := RandSeed * $08088405 + 1;
  RandSeed := Temp;
  Result := (UInt64(Cardinal(ARange)) * UInt64(Cardinal(Temp))) shr 32;
end;

因此,如果您知道其中一个生成的随机数,您就可以轻松猜出下一个生成的随机数...

他们是否可以替代 random 来生成我的 12 字节随机字节?

【问题讨论】:

  • 下一个随机数是什么重要吗?顺便说一句,三个 32 位数字不适合一个 64 位数字。 maxint*maxint ≈ maxint64
  • 是的,因为如果一个人知道一个随机生成的数字,他可以猜出下一个生成的所有不好的数字。不是适合 64 位,而是适合 96 位(12 字节)
  • 不好,为什么?例如,当您添加盐进行散列时,谁在乎盐来自哪里或下一个将是什么,只要您将其应用于特定的散列,并且有很多不同的盐。我很好奇在什么情况下不知道下一个数字很重要。
  • 使用随机数作为密钥时。你给别人一把钥匙,所以这个人可以猜到你将给别人的下一把钥匙。我需要一个随机数的随机数
  • Cryptographically secure random numbers 与日常随机数有很大不同。如果您正在尝试编写密码库,请忘记它 - 如果您被困在这里,那么您就没有希望构建任何有用的东西。但是,如果您需要使用密码学,那么只需使用库即可。这就是它们存在的原因——因为试图在痛苦中终结自己。

标签: delphi


【解决方案1】:

我看到了三种选择。

我们发布了一个开源AES-256 based Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)。它有一个经过验证的熵生成器,您可以拥有多个生成器(例如,每个线程一个)。使用AES-NI硬件加速,速度非常快。

或者,如果你想生成唯一的 ID,你可以使用类似的代码,一次生成一个 32 位随机值:

{$ifdef CPUINTEL}
/// get 32-bit value from NIST SP 800-90A compliant RDRAND Intel x86/x64 opcode
function RdRand32: cardinal;
{$ifdef CPU64}
{$ifdef FPC}nostackframe; assembler;
asm
{$else}
asm
  .noframe
{$endif FPC}
{$endif CPU64}
{$ifdef CPU32}
asm
{$endif}
  // rdrand eax: same opcodes for x86 and x64
  db $0f,$c7,$f0
  // returns in eax, ignore carry flag (eax=0 won't hurt)
end;
// https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
{$endif}

var
  rs1: cardinal = 2654435761;
  rs2: cardinal = 668265263;
  rs3: cardinal = 3266489917;

function Random32: cardinal;
begin
  {$ifdef CPUINTEL}
  if cfRAND in CpuFeatures then begin
    result := RdRand32;
    exit;
  end;
  {$endif}
  result := rs1;
  rs1 := ((result and -2)shl 12) xor (((result shl 13)xor result)shr 19);
  result := rs2;
  rs2 := ((result and -8)shl 4) xor (((result shl 2)xor result)shr 25);
  result := rs3;
  rs3 := ((result and -16)shl 17) xor (((result shl 3)xor result)shr 11);
  result := rs1 xor rs2 xor result;
end;

它将使用最新 Intel CPU 上可用的基于硬件的 PRNG,或 P. L'Ecuyer 的快速 gsl_rng_taus2 生成器(句点=2^88,即大约 10^26),这比Random() 中的模式要好得多。对于多线程,对 rs1、rs2 和 rs3 使用 threadvar 而不是 var。并且不要忘记对初始值进行异或,例如具有一些最小熵,至少 QueryPerformanceCounter()。

最后但同样重要的是,如果您想要一些独特的值,而不是完全随机的,您可以简单地使用:

var g: TGUID;
...
CreateGUID(g);

这里生成的 TGUID 被操作系统知道是唯一的。您可以轻松地使用 128 位的 TGUID 内容,它可以以比 3*32 位更好的方式用作密钥,甚至在 Internet 上也是如此。如果你需要的是唯一性,而不是随机性,很多系统只是依赖于这个 API 调用。您可以使用字符串表示形式,也可以使用 128 位 = 4*32 位二进制内容。

【讨论】:

  • 他不想要唯一性。从语言的角度来看,只能有两种选择。这就是替代的意思。在两个选项之间切换。这已被接受,这变成了一个推荐问题。 Arnaud,你明白这里结束的问题吗?
  • 问题不清楚,这就是为什么我以 3 个提案结束。当然,第一个似乎最合适,直接满足了独立 Delphi PRNG 类的需求。如果他不想要唯一性,那么只有我们的 AES-PRNG 和 RdRand32 函数会返回真正的随机性——只有在 CPU 支持的情况下才会返回真正的随机性。 gsl_rng_taus2() 不是加密的,只是很好的快速随机值。
  • Arnaud,感谢您的回答.. 我开始研究您的算法,但不幸的是我的计算机不支持 CpuFeatures 中的 cfRAND。所以我需要使用 rs1、rs2、rs3。问题是,如果用户知道一个生成的密钥,那么他可以猜测将生成的下一个密钥:(知道如何避免这种情况吗?
  • @lok​​i 然后你需要为生成器播种。在这种情况下,我认为获得正确熵的可能性不大。您可以使用QueryPerformanceCounter 并将 rs1、rs2、rs3 与返回值进行异或,并将某些 CreateGUID 值异或。但是为了获得好的熵,你可能需要更强大的东西,比如我们用于 TAESPRNG.GetEntropy 的东西。但是 gsl_rng_taus2 是一个确定性生成器,因此任何用户都可以猜测下一个值。在这种情况下,TAESPRNG 将是加密随机性的最佳选择。或调用 Windows API。
  • @Arnaud 谢谢!我读了你的代码,我想我会使用 Windows API,以防处理器不支持随机
【解决方案2】:

Delphi 的线性同余生成器确实不适合生成加密安全的随机数据。你绝对不能依赖它来完成这项任务。它不是为此目的而设计的,它旨在用于其他场景。

不要尝试自己实现。这很难做到正确,需要大量的知识和专业知识。人们创建不安全代码的最常见原因之一是当他们试图在没有足够知识的情况下编写自己的加密货币时。不要掉进那个陷阱。使用受信任的密码库。

【讨论】:

  • 感谢大卫!我完全同意你的看法,但我还没有找到一个很好的图书馆来做到这一点......我会尝试在互联网上查找
  • 搜索 CSPRNG
  • 感谢 david .. 很难找到一个好的和经过验证的库,即使是 windows 制作的 WRNG(最常用的 PRNG)也不好(即:eprint.iacr.org/2007/419.pdf - 见底部结论)
  • windows advapi32.dll 包含一个 windows 内置随机数生成器,供 win 内置加密库使用...(查看 CryptGenRandom)。你也可以使用 intel 的 asm 命令 RDRAND(实际上 Linux 的人不会将它用于他们的随机生成器,因为他们对此有不好的感觉 - 可能是 NSA 的后盾;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多