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

1 篇文章 0 订阅
1 篇文章 0 订阅

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

  • 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/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;

    /* myString will be a string of 32 random bytes */
    randombytes_buf(myString, 32);

    /* myInt will be a random number between 0 and 9 */
    myInt = randombytes_uniform(10);
}

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

Java中的密码安全随机

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

SecureRandom csprng = new SecureRandom();

byte[] randomBytes = new byte[32];

csprng.nextBytes(randomBytes);

备注:SecureRandom类,此类提供加密的强随机数生成器 (RNG)。
文件头要加入该句import java.security.SecureRandom;
注意:不要在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()

在openssl抹掉crypto.randomBytes之前,你最好的选择是使用node-sodium(来替代这个函数)

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。

*本文译者:felix,翻译自:https://paragonie.com/blog/2016/05/how-generate-secure-random-numbers-in-various-programming-languages,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端加密所需的js类库,包含各种加密方法,文件列表: crypto-js-develop, 0 , 2017-06-02 crypto-js-develop\.gitignore, 23 , 2017-06-02 crypto-js-develop\.jshintrc, 1036 , 2017-06-02 crypto-js-develop\CONTRIBUTING.md, 482 , 2017-06-02 crypto-js-develop\Gruntfile.js, 1133 , 2017-06-02 crypto-js-develop\LICENSE, 1169 , 2017-06-02 crypto-js-develop\README.md, 4010 , 2017-06-02 crypto-js-develop\docs, 0 , 2017-06-02 crypto-js-develop\docs\QuickStartGuide.wiki, 18085 , 2017-06-02 crypto-js-develop\grunt, 0 , 2017-06-02 crypto-js-develop\grunt\config, 0 , 2017-06-02 crypto-js-develop\grunt\config\clean.js, 107 , 2017-06-02 crypto-js-develop\grunt\config\copy.js, 362 , 2017-06-02 crypto-js-develop\grunt\config\jshint.js, 354 , 2017-06-02 crypto-js-develop\grunt\config\jsonlint.js, 259 , 2017-06-02 crypto-js-develop\grunt\config\modularize.js, 8622 , 2017-06-02 crypto-js-develop\grunt\config\update_json.js, 999 , 2017-06-02 crypto-js-develop\grunt\tasks, 0 , 2017-06-02 crypto-js-develop\grunt\tasks\modularize.js, 2325 , 2017-06-02 crypto-js-develop\package.json, 1143 , 2017-06-02 crypto-js-develop\src, 0 , 2017-06-02 crypto-js-develop\src\aes.js, 8157 , 2017-06-02 crypto-js-develop\src\cipher-core.js, 29262 , 2017-06-02 crypto-js-develop\src\core.js, 22209 , 2017-06-02 crypto-js-develop\src\enc-base64.js, 3570 , 2017-06-02 crypto-js-develop\src\enc-utf16.js, 3607 , 2017-06-02 crypto-js-develop\src\evpkdf.js, 3558 , 2017-06-02 crypto-js-develop\src\format-hex.js, 1410 , 2017-06-02 crypto-js-develop\src\hmac.js, 3666 , 2017-06-02 crypto-js-develop\src\lib-typedarrays.js, 1869 , 2017-06-02 crypto-js-develop\src\md5.js, 9092 , 2017-06-02 crypto-js-develop\src\mode-cfb.js, 1698 , 2017-06-02 crypto-js-develop\src\mode-ctr-gladman.js, 1899 , 2017-06-02 crypto-js-develop\src\mode-ctr.js, 1062 , 2017-06-02 crypto-js-develop\src\mode-ecb.js, 484 , 2017-06-02 crypto-js-develop\src\mode-ofb.js, 924 , 2017-06-02 crypto-js-develop\src\pad-ansix923.js, 854 , 2017-06-02 crypto-js-develop\src\pad-iso10126.js, 706 , 2017-06-02 crypto-js-develop\src\pad-iso97971.js, 505 , 2017-06-02 crypto-js-develop\src\pad-nopadding.js, 138 , 2017-06-02 crypto-js-develop\src\pad-zeropadding.js, 609 , 2017-06-02 crypto-js-develop\src\pbkdf2.js, 4125 , 2017-06-02 crypto-js-develop\src\rabbit-legacy.js, 6224 , 2017-06-02 crypto-js-develop\src\rabbit.js, 6195 , 2017-06-02 crypto-js-develop\src\rc4.js, 3081 , 2017-06-02 crypto-js-develop\src\ripemd160.js, 8812 , 2017-06-02 crypto-js-develop\src\sha1.js, 3722 , 2017-06-02 crypto-js-develop\src\sha224.js, 1521 , 2017-06-02 crypto-js-develop\src\sha256.js, 5206 , 2017-06-02 crypto-js-develop\src\sha3.js, 10236 , 2017-06-02 crypto-js-develop\src\sha384.js, 1833 , 2017-06-02 crypto-js-develop\src\sha512.js, 13077 , 2017-06-02 crypto-js-develop\src\tripledes.js, 23837 , 2017-06-02 crypto-js-develop\src\x64-core.js, 8562 , 2017-06-02 crypto-js-develop\test, 0 , 2017-06-02 crypto-js-develop\test\aes-profile.js, 1104 , 2017-06-02 crypto-js-develop\test\aes-test.js, 4997 , 2017-06-02 crypto-js-develop\test\cipher-test.js, 17242 , 2017-06-02 crypto-js-develop\test\des-profile.js, 1040 , 2017-06-02 crypto-js-develop\test\des-test.js, 6318 , 2017-06-02 crypto-js-develop\test\enc-base64-test.js, 3089 , 2017-06-02 crypto-js-develop\test\enc-hex-test.js, 475 , 2017-06-02 crypto-js-develop\test\enc-latin1-test.js, 503 , 2017-06-02 crypto-js-develop\test\enc-utf16-test.js, 2121 , 2017-06-02 crypto-js-develop\test\enc-utf8-test.js, 1445 , 2017-06-02 crypto-js-develop\test\evpkdf-profile.js, 326 , 2017-06-02 crypto-js-develop\test\evpkdf-test.js, 1375 , 2017-06-02 crypto-js-develop\test\format-openssl-test.js, 1795 , 2017-06-02 crypto-js-develop\test\hmac-md5-profile.js, 947 , 2017-06-02 crypto-js-develop\test\hmac-md5-test.js, 2662 , 2017-06-02 crypto-js-develop\test\hmac-sha224-test.js, 2812 , 2017-06-02 crypto-js-develop\test\hmac-sha256-test.js, 2852 , 2017-06-02 crypto-js-develop\test\hmac-sha384-test.js, 3012 , 2017-06-02 crypto-js-develop\test\hmac-sha512-test.js, 3172 , 2017-06-02 crypto-js-develop\test\kdf-openssl-test.js, 644 , 2017-06-02 crypto-js-develop\test\lib-base-test.js, 3132 , 2017-06-02 crypto-js-develop\test\lib-cipherparams-test.js, 2654 , 2017-06-02 crypto-js-develop\test\lib-passwordbasedcipher-test.js, 966 , 2017-06-02 crypto-js-develop\test\lib-serializablecipher-test.js, 2365 , 2017-06-02 crypto-js-develop\test\lib-typedarrays-test.js, 2249 , 2017-06-02 crypto-js-develop\test\lib-wordarray-test.js, 3303 , 2017-06-02 crypto-js-develop\test\md5-profile.js, 743 , 2017-06-02 crypto-js-develop\test\md5-test.js, 2772 , 2017-06-02 crypto-js-develop\test\mode-cbc-test.js, 2024 , 2017-06-02 crypto-js-develop\test\mode-cfb-test.js, 2103 , 2017-06-02 crypto-js-develop\test\mode-ctr-test.js, 2213 , 2017-06-02 crypto-js-develop\test\mode-ecb-test.js, 1484 , 2017-06-02 crypto-js-develop\test\mode-ofb-test.js, 2042 , 2017-06-02 crypto-js-develop\t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值