我该在哪里获取可靠的熵源(真随机性byte[])?

3

目前,我正在寻找一种方法来提高我的Android应用程序(一款纸牌游戏)中的随机性质量。先前估计,在我的情况下(52!排列),至少需要226位熵(226个随机位)。

我计划将此byte[]用作SecureRandom的种子:

SecureRandom random = new SecureRandom();
random.setSeed(/* insert seed here, byte[] */)

问题是 -- 在Android上,我在哪里可以可靠地获得这么多(至少226位)随机比特,最好不需要任何权限和互联网。此外,它应该能在设备和API级别无关的情况下工作。


请不要在标题中重复使用android的tag。 - Phantômaxx
2
“最好不需要任何权限和互联网…” 我非常怀疑这是可能的。例如,您需要权限来使用麦克风捕捉环境噪声,或者需要互联网来使用 random.org 或类似服务。 - T.J. Crowder
1
@KlingKlang - 好的,谢谢你的指导。 - Sergey Emeliyanov
1
SecureRandom 在 Linux 和很可能是 Android 上使用 /dev/random - Peter Lawrey
@Eugene - 那只是伪随机,不是真正的熵。 - T.J. Crowder
显示剩余7条评论
2个回答

3

在 Java 8 或更高版本中,您可以使用

SecureRandom rand = SecureRandom.getInstanceStrong();

为了在您的平台上获得最强的随机性。如果需要明确指定,可以使用以下代码:

SecureRandom rand = SecureRandom.getInstance("NativePRNGBlocking");

此处使用Linux系统中的/dev/random熵。但如果不可用,则可能无法正常运行。

https://www.synopsys.com/blogs/software-security/proper-use-of-javas-securerandom/


另一种方法是基于用户输入创建随机性,通过对先前事件的System.nanoTime()进行SHA256或更高级的处理。


1
没有权限访问麦克风或者获取random.org的字节(需要互联网),我唯一想到的就是用户本身:展示一个空白方块,用户在其中移动手指,指导他们尽可能随机地进行操作,最好持续几秒钟,并使用触摸数据。(我似乎记得我曾经使用过的一个应用程序——TrueCrypt?——就是这样做的。)你甚至可以在他们的人类随机性之上添加一些伪随机性,试图避免人们通过极其精确的可重复运动来操纵系统。
如果您放宽要求,您可能可以从麦克风(环境噪音)和/或加速度计中获得一些相当好的熵。当然,如果您请求网络访问权限,您可以从http://random.org下载真正的随机数据。

2
如果他们不关心权限,从麦克风或加速度计数据获取字节流,然后将其添加到伪随机数中似乎是一个很好的选择。 - Josh White
非常好的点子,也许我可以根据上一轮游戏中的动作生成随机字节。 - Sergey Emeliyanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接