在 C 中使用内存地址播种随机数 - 不推荐?

问题描述 投票:0回答:1

我正在学习 C 语言中的随机数生成。在探索不同的方法时,我想到了使用内存地址作为随机数生成器(如 rand())的种子的想法。但是,我不确定这是否是一个好的做法。

这是我的问题:

为什么不建议使用内存地址作为 rand() 的种子? 这种方法是否存在安全问题或限制? 在 C 中播种随机数生成器的首选方法是什么? 会起作用吗?

附加信息:

我知道 rand() 是一个伪随机数生成器,但我对种子方面特别感兴趣。 如果不鼓励使用内存地址,是否有其他方法可以出于(非关键)目的从它们中提取一些随机性?

我一直在做一个基本项目来熟悉 C 中的随机数,这个问题是在探索不同的播种方法时出现的。 在这里我试图用 rand() 获取随机数

#include<stdio.h>

int main(){
    int num=1;
    int *ptr;

    ptr = &num;
printf("%u\n",ptr);

int address_holder;
address_holder = ptr;
int random_number = address_holder & 0x000000FF

// int random_number = address_holder % 100
printf("random number ; %u\n");
    return 0;
}

我期望每次运行程序时都会生成一个随机数。 我注意到如果我使用 %u 来打印地址,它会导致内存地址被打印为数字 结果:失败,到目前为止我无法使用 %u 存储指针的打印值。

c
1个回答
0
投票

地址可能由操作系统随机化,以使利用某些错误变得更加困难。然而,有很多理由避免使用地址随机性来播种任何 RNG,甚至是非关键的 RNG:

  • 在某些情况下可能不适用随机化。例如,没有使用 PIE(位置无关可执行文件)编译的程序将始终加载到固定地址。禁用随机化运行的程序(例如在调试器下)将始终加载在可预测的地址。
  • 实际应用的随机化量差异很大。例如,在许多版本的 Windows 上,地址在每次启动时都会随机化一次,因此在您重新启动计算机之前一直保持一致。在 Linux 上,地址的熵可以少至 20 位(甚至在 32 位系统上也更少),特别是因为大多数段的最后 12 位都不是随机的。
  • 使用地址来播种 RNG 使程序的可观察行为取决于随机地址。如果对随机数据有足够的观察,攻击者可以对种子进行逆向工程并破坏程序的 ASLR,从而使该防御变得毫无意义。如果您的程序存在任何内存损坏错误,那么您就让攻击者的工作变得更加容易。

出于所有这些原因,您应该永远不使用地址随机性来播种 RNG。使用高质量的随机源,例如 Linux 上的 getrandom() 系统调用或 Windows 上的 CryptGenRandom,为您的应用程序生成足够的熵; 128 到 256 位通常足以生成高质量的 PRNG。

© www.soinside.com 2019 - 2024. All rights reserved.