如何在各种编程语言中生成安全的随机数

生成安全的随机数据指什么?为什么要生成安全的随机数据?之前一些文献中这并没有很好得说明如何生成“安全”的随机数。所以,这里将介绍如何在下面的编程语言中安全地生成随机数。

    C/C++

    Java

    .NET

    Node.js

    PHP

    Python

    Ruby

需要包含的一般条件

这篇文章的所有方案都必须只从内核的CSPRNG(Cryptographically Secure Pseudo-Random Number Generator,密码安全的伪随机数生成器)中读取,并且失败后立即关闭。用户空间的RNG以及回退到不安全的RNG都是不允许的。所以,根据平台的不同,使用下面的熵源:

  Windows:
        RtlGenRandom
  Linux:
        getrandom (如何可用的话)
            它的方法是正确的,在播种之前会阻塞,之后不再播种。
        /dev/urandom (老的Linux内核)
            对于在Linux启动时运行的软件,查询/dev/random,直到它可用。这意味着那时/dev/urandom已经播种了,你可以安全地从/dev/urandom中读取内容了,可以用到你的密码中。不要从/dev/random中读取。

   OpenBSD:
        getentropy()
        arc4random_buf() 使用ChaCha20加密算法 (不是RC4)
   其它类Unix系统 (包括OS X):
        /dev/urandom

这里不考虑依赖于haveged,egd等程序的解决方案。

C/C++中的密码安全随机

最简单和安全的方法是,把libsodium库添加到工程的依赖库中,使用randombytes_buf()函数。

这里查看libsodium是怎样实现这些函数的。PHP团队在其内部的random_bytes函数实现中采用了与此类似的方法。

#include "sodium.h"

int foo() {

    char myString[32];

    int myInt;

    randombytes_buf(myString, 32);

    /* myString will be a string of 32 random bytes */

    myInt = randombytes_uniform(10);

    /* myInt will be a random number between 0 and 9 */

}

如果可以的话就使用libsodium,下面的其它语言也是如此。

Java中的密码安全随机

除了使用libsodium(推荐),也可以直接使用Java的SecureRandom类:

SecureRandom csprng = new SecureRandom();

byte[] randomBytes = new byte[32];

csprng.nextBytes(randombytes);

注意:不要在Linux上使用SecureRandom.getInstanceStrong(),不要被名称误导,它等同于读取/dev/random,这个是不安全的。Java8中new SecureRandom()默认读取/dev/urandom,这才是你需要的。

.NET(C#)中的密码安全随机

普遍采用的方案是使用System.Security.Cryptography.RNGCryptoServiceProvider,比如:

RandomNumberGenerator csprng = new RNGCryptoServiceProvider();

byte[] rawByteArray = new byte[32];

csprng.getBytes(rawByteArray);

如果你需要生成密码上安全的整数,查看Inferno(一个Stan Drapkin写的.NET密码库)中的CryptoRandom类的实现方法。

Node.js中的密码安全随机

不要使用crypto.randomBytes()

var csprng = require("sodium").Random;

var bytes = csprng.randombytes_buf(32);

PHP中的密码安全随机

如果你运行的是PHP 7,有一个内置的函数:

$string = random_bytes(32);

$integer = random_int(0, PHP_INT_MAX);

如何你用的还是PHP 5, 获取random_compat,然后同PHP 7一样使用相同的API。

composer require paragonie/random_compat:^2

请使用版本2。版本1会回退到OpenSSL,如果没有其它可用的熵源,它会导致安全问题。然而,一些人为了兼容性,会明确地使用版本1。

如果你在写一个供别人在他们的工程中使用的PHP 5库,将你的composer.json条件字符串设置为^1|^2。相反,如果你在写一个应用程序,将条件字符串设置为^2。

Python中的密码安全随机

如果你没有使用libsodium: 如果你需要随机字节,使用os.urandom().

如果你需要其它格式的随机数据,你需要使用random.SystemRandom(),而不是random。

import sys

import random

# Random bytes

bytes = os.urandom(32)

csprng = random.SystemRandom()

# Random (probably large) integer

int = csprng.randint(0, sys.maxint)

Ruby中的密码安全随机

不要使用Ruby的SecureRandom!

与名称无关,它不是最好的CSPRNG。幸运的是,Tony Arcieri(密码专家,Cryptosphere 的设计者,全面的密码应用工程师)给Ruby community提供了一个安全的选择,将libsodium的sysrandom接口移植到了Ruby gem中。

建议:使用Sysrandom代理SecureRandom。

安装sysrandom:

gem install sysrandom

Sysrandom与SecureRandom API兼容。可以通过打补丁来代替SecureRandom。

时间: 2025-01-14 13:53:49

如何在各种编程语言中生成安全的随机数的相关文章

java中生成不重复随机数(据HashSet特性)

import java.util.HashSet; public class RandomNumbers { /** * 随机指定范围内N个不重复的数 利用HashSet的特征,只能存放不同的值 * * @param min * 指定范围最小值 * @param max * 指定范围最大值 * @param n * 随机数个数 * @param HashSet<Integer> * set 随机数结果集 */ public static void randomSet(int min, int

编程语言中那些有趣的命名

学习NodeJS的时候,一定会用到其包管理器npm.npm的字面意思是node package manager,实际的含义也是这样,但是npm真正的英文名却是"npm is not an acronym",意思是"npm不是一个缩写",所以如果要问npm是什么单词的缩写,那么回答就是"'npm是不是一个缩写'的缩写". 这种计算机科学中的"饶舌"现象叫作递归缩写. 递归缩写(Recursive acronym)即递归首字缩写,

Linux应用环境实战10:Bash脚本编程语言中的美学与哲学(转)

阅读目录 一.一切皆是字符串 二.引用和元字符 三.字符串从哪里来.到哪里去 四.再加上一点点的定义,就可以推导出整个Bash脚本语言的语法了 五.输入输出重定向 六.Bash脚本语言的美学:大道至简 总结: 我承认,我再一次地当了标题党.但是不可否认,这一定是一篇精华随笔.在这一篇中,我将探讨Bash脚本语言中的美学与哲学. 这不是一篇Bash脚本编程的教程,但是却能让人更加深入地了解Bash脚本编程,更加快速地学习Bash脚本编程. 阅读这篇随笔,不需要你有Bash编程的经验,但一定要和我一

Swift编程语言中如何实现自定义类型的for-in循环(基于Swift 2.2)

我们在Swift编程语言中常常会用到for-in循环(在编程语言术语中又被称为for-each).此外,从Swift 2.2版本起,for循环将只支持for-in形式,而不支持for i = 0; i < n; i+=1 { }这种形式了,若要使用这种形式的话,只得用while或repeat-while来代替,或想办法转为for-in. 在Swift中,标准库已经定义了许多类型可直接支持for-in循环形式,比如Range.Array.Set.Dictionary等等.那么我们是否能自己定义一个

Python历史以及Python在编程语言中的定位

提及阿姆斯特丹你可以联想到郁金香,也可以联想到关于荷兰的一些东东,当然你如果是计算机爱好一族的话,你就一定会关心Python历史,以下就有关于Python历史的介绍. AD: 以本人的观点看来,Python这种语言是非常优美和强大在实际的应用中,是由专门为非专业程序员设计的计算机语言,而拥有很优美的语言Python为什么会用Python命名呢?如果你想对其有所了解,你也不妨看看关于Python历史的介绍. Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹

如何在C#中生成与PHP一样的MD5 Hash Code

原文:如何在C#中生成与PHP一样的MD5 Hash Code 最近在对一个现有的系统进行C#改造,该系统以前是用PHP做的,后台的管理员登陆用的是MD5加密算法.在PHP中,要对一个字符串进行MD5加密非常简单,一行代码即可: md5("Something you want to encrypt.") 直接调用md5()方法,然后将要进行MD5加密的字符串传进去,就可以得到返回的hash code.在C#中应该也会有对应的算法吧!对吗?我首先尝试了下面的代码,结果得到的hash co

Linux江湖10:Bash脚本编程语言中的美学与哲学

我承认,我再一次地当了标题党.但是不可否认,这一定是一篇精华随笔.在这一篇中,我将探讨Bash脚本语言中的美学与哲学.这不是一篇Bash脚本编程的教程,但是却能让人更加深入地了解Bash脚本编程,更加快速地学习Bash脚本编程.阅读这篇随笔,不需要你有Bash编程的经验,但一定要和我一样热衷于探索各种编程语言的本质,感悟它们的魅力. 其实早就想写关于Bash的东西了.前几天看到有博友在院子里发学习Bash的心得(这里http://www.cnblogs.com/viroyiheng/p/3988

Linux Bash脚本编程语言中的美学与哲学

我承认,我再一次地当了标题党.但是不可否认,这一定是一篇精华随笔.在这一篇中,我将探讨Bash脚本语言中的美学与哲学. 这不是一篇Bash脚本编程的教程,但是却能让人更加深入地了解Bash脚本编程,更加快速地学习Bash脚本编程. 阅读这篇随笔,不需要你有Bash编程的经验,但一定要和我一样热衷于探索各种编程语言的本质,感悟它们的魅力. 其实早就想写关于Bash的东西了. 我们平时喜欢对编程语言进行分类,比如面向过程的编程语言.面向对象的编程语言.函数式编程语言等等.在我心中,我认为Bash就是

C#中生成的随机数为什么不随机?

from:https://www.xcode.me/more/net-csharp-generate-random 随机数生成方法可以说是任何编程语言必备的功能,它的重要性不言而言,在C#中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成5个随机数: for (int i = 0; i < 5; i++) { Random random = new Random(); Console.WriteLine(random