如何在各種程式語言中生成安全的隨機數
生成安全的隨機資料指什麼?為什麼要生成安全的隨機資料?之前一些文獻中這並沒有很好得說明如何生成“安全”的隨機數。所以,這裡將介紹如何在下面的程式語言中安全地生成隨機數。
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。
相關文章
- numpy各種生成隨機數的方法隨機
- MATLAB生成服從各種分佈的隨機數函式Matlab隨機函式
- 更安全的隨機數生成隨機
- 幾種生成隨機數方法隨機
- C語言程式生成指定範圍的不重複的隨機數C語言隨機
- 微信小程式生成隨機數微信小程式隨機
- python生成隨機數、隨機字串Python隨機字串
- JavaScript 生成隨機數JavaScript隨機
- Go 語言控制檯輸入&生成隨機數Go隨機
- Matlab 隨機生成兩個數值之間的隨機數Matlab隨機
- Python如何隨機生成1到100的隨機數?Python隨機
- Linux Shell 生成隨機數和隨機字串Linux隨機字串
- matlab 生成隨機數序列Matlab隨機
- C++生成隨機數C++隨機
- 隨機數生成器隨機
- java隨機數生成原理Java隨機
- c語言中預設引數的兩種型別C語言型別
- 偽隨機數C語言程式設計隨機C語言程式設計
- Solidity陷阱:以太坊的隨機數生成Solid隨機
- 如何生成指定分佈的隨機數隨機
- 【java】隨機生成6位的數字Java隨機
- 生成指定區間的隨機小數隨機
- 生成某個範圍的隨機數隨機
- Python中如何生成隨機數?Python隨機
- 使用Math類生成隨機數隨機
- 前端學習程式碼例項-JavaScript 生成隨機數前端JavaScript隨機
- 如何在Python語言中跳出for迴圈?Python
- 程式語言中的 DUCK TYPING
- Python生成隨機數random模組Python隨機random
- Golang生成區間隨機整數Golang隨機
- 巧用物件,生成不重複隨機數物件隨機
- 怎麼用Python生成隨機數Python隨機
- 偽隨機數是什麼?偽隨機數生成方法有哪些?隨機
- 隨機數種子(random seed)隨機random
- Linux 系統生成隨機密碼的10種方法Linux隨機密碼
- 自動生成介面各種逆向組合引數
- Go 語言中的兩種 slice 表示式Go
- 聊一聊隨機數安全隨機
- 理解函數語言程式設計語言中的組合--前言(一)函數程式設計