2018年12月14日 星期五

C Library rand()

產生虛擬亂數 (pseudo-random number),不是真的亂數,也不是機密的,而是一系列看起來像亂數的數列,這些數字實際上是有固定順序的。

#include <stdlib.h>

void srand(unsigned int seed); // 設定函式庫內部的 seed,一開始預設是 1。

int rand(void); // 依據 seed 運算產生範圍為 [0, RAND_MAX] 的虛擬亂數回傳,並儲存為新的 seed。

int rand_r(unsigned int *seedp); //

rand_r() 為 reentrant 版的 rand(),需要傳入儲存 seed 的記憶體指標,在 thread 程式得以不被其它 thread 干擾來產生同樣的數列。在 POSIX.1-2008 標注為廢棄。

POSIX.1-2001 rand() 和 srand() 的實作範例:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned int seed) {
    next = seed;
}

注意

  • 虛擬亂數是有一定順序的,知道 seed 就知道下一個產生的值。假設初始 seed 設為目前的時間秒數,已知是今年的話,大約有 225 個可能的值,縮小範圍後依現今運算能力很容易試出來。
  • 產生序列的最低 bit 固定 01010101..,其實不夠亂。
  • 1995 發現 Netscape 瀏覽器產生的 SSL session keys 使用時間和 process ID 作為 seed,猜得到,所以 SSL sessions 可在幾分鐘內破壞。...

以上經驗告訴我們,作為 secure 的虛擬亂數產生器,有兩個基本原則:

  1. seed 必須是無法預測的 (實際上只能難以預測?)。要有足夠的可能性,例如 2128 就足夠 (隨著計算能力越來越強,暴力破解越容易,需要更多 bit),所有可能出現的機率相同,沒有東西讓攻擊者可以縮小範圍。
  2. 產生虛擬亂數的 algorithm 必須是 secure,pseudorandom bits 沒有可辨別的 patterns。即使攻擊者學到或猜到一些 pseudorandom bits,也無法預測其它 pseudorandom bits。

參考

  1. https://inst.eecs.berkeley.edu//~cs161/fa08/Notes/random.pdf

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...