大量の疑似乱数データを予測可能に生成

大量の疑似乱数データを予測可能に生成

安価な2TB HDD(1枚あたり60€)を購入しましたが、使用する前に読んだときに入力したデータが返されることを確認したかったです。私はここに入れた大容量ファイルをコピーし、彼らが返したデータのハッシュをチェックして安いサムドライブを調べました(実際のストレージ容量が使い果たされた後、データを削除したドライブが見つかりました)。残念ながら、2TBファイルはありません。

2TBの疑似乱数データを作成してディスクに書き込んでディスクにハッシュしようとしています。次に、同じデータをハッシュ関数に直接書き、この方法で生成する必要があるハッシュ値を取得したいと思います。疑似乱数関数は暗号化方式で安全である必要はなく、エントロピーデータをすばやく生成するだけです。

数値を含む変数をハッシュし、ハッシュ値をstdoutに印刷し、変数を増やして繰り返し実行するスクリプトを作成すると、高速CPUでもデータレートが遅すぎます。 5倍遅くなります(60kByte / sもできません)。

今私できるこうしてみましたteeが、とても悪い考えなので、同じデータを繰り返し再現することはできません。

理想的には、いくつかの短い引数(数値、文字列、無関係)をプログラムに渡し、標準出力から任意に大量のデータを取得し、データはすべての呼び出しで同じです。

ベストアンサー1

0(***)を暗号化するだけです。

暗号化はまさにあなたが望むものです。暗号化されたゼロは任意のデータのように見えます。復号化後、再びゼロに変更します。キーを知り、同じパスワード設定(**)を使用し続ける限り、決定的で反復可能で元に戻すことができます。

任意のデータでドライブを上書きする例cryptsetup

cryptsetup open --type plain --cipher aes-xts-plain64 /dev/deletedisk cryptodeletedisk
# overwrite with zeroes
pv < /dev/zero > /dev/mapper/cryptodeletedisk
# verify (also drop caches or power cycle)
echo 3 > /proc/sys/vm/drop_caches
pv < /dev/mapper/cryptodeletedisk | cmp - /dev/zero
### alternatively, run badblocks in destructive mode:
badblocks -w -b 4096 -t 0 -v -s /dev/mapper/cryptodeletedisk

これは、AES-NIを使用する最新システムのディスク速度を最大限に活用する必要があります。

エラーが見つからない場合は、ドライブがランダムデータで完全に上書きされ、再読み込み時に正しいデータが返されます。


同じランダムデータを繰り返し転送するためにcryptsetupを使用する例(実際のストレージは含まれていません)。

この例では、/dev/zeroこれをデータソースとして使用せずに、正確にゼロのあるランダムに大きなスパースファイルを作成できることを利用しています。

# truncate -s 1E exabyte_of_zero
# cryptsetup open --type plain --cipher aes-xts-plain64 --readonly exabyte_of_zero exabyte_of_random
Enter passphrase for exabyte_of_zero: yourseed
# hexdump -C -n 64 /dev/mapper/exabyte_of_random
# cat /dev/mapper/exabyte_of_random | something_that_wanted_random_data

これは、ファイルシステムがスパースファイルをサポートし、副作用がない場合にのみ機能します(tmpfsでは機能しません)。

注:これは単なる例であり、実際にこれらの仮想EBデバイスを作成すると副作用が発生する可能性があります。ユースケースに適したサイズにサイズを制限し、バックアップスクリプトがファイルを選択して圧縮しない場所にファイルを保存します。


cryptsetup読み取り可能なブロックデバイスが提供され検索可能であるため、それを使用してファイルの中央のどこかでデータ比較を開始することもできます。また、これを使用して、ランダムオフセットからランダムデータを分析し、それが実際にランダムか反復されていないかを確認することもできます(*)。従来のPRNGでは、通常、すべてを最初から再生成する必要があります。


cryptsetuproot権限が必要です(結果的なデバイスマッパーデバイスは他のユーザーが読めるようにすることができますが)。

ルートアクセスがない場合は、openssl0を暗号化して任意のデータを生成できます。 (コメントにはすでに言及されています。)

$ openssl enc -pbkdf2 -aes-256-ctr -nosalt \
      -pass pass:yourseed < /dev/zero \
      | hexdump -C -n 64
00000000  62 5e 3d cd 39 dc d6 a2  bb 73 2d 0f 63 b1 f1 75  |b^=.9....s-.c..u|
00000010  4d 84 f5 75 cb b6 1e 33  9c e8 41 9c 76 4b 7e 12  |M..u...3..A.vK~.|
00000020  c2 90 d5 93 2d a9 9e a0  48 bd b8 3e a5 1a d6 f7  |....-...H..>....|
00000030  2c a6 e0 07 4d 5a 45 31  13 dc ef 97 df 76 c5 b8  |,...MZE1.....v..|
00000040

このアプローチも提案される。coreutils ドキュメントランダムデータソース方法として「シード値が与えられると、繰り返し可能な任意の量の疑似乱数データが​​生成されます。」


暗号化されたゼロの代わりに既存のPRNGを使用することもできます。私はそれを提供する標準的なツールがわからないということです。したがって、この方法には、目的のPRNGアルゴリズム/ライブラリを選択し、数行のコードを作成してデータを生成することが含まれます。

shred良いPRNGがありますが、直接シードまたはパイプできないため、ここでは使用できません。

tee単一のランダムソースからのデータを複数のプロセスに多重化することは可能ですが、データはすぐに並列に消費される必要があります(例:2つの並列テキストファイルを混在させる)、したがって、これはデータが同じでなければならないが後で再現する必要がない場合にのみ適用されます。


(*)暗号化時に正しいパスワード設定を選択することが非常に重要です。たとえば、aes-xts-plain2 TB のデータが複製された後は にあるため、aes-xts-plain64使用しないでくださいaes-xts-plain

(**)パスワード設定が異なると結果も異なります。この回答に示されているコマンドはいくつかのデフォルト設定に依存しているため、長期的にはデータが同じでない可能性があります。たとえば、cryptsetupは256ビットキーまたは512ビットキーを使用できますが、opensslはデフォルトの繰り返し回数を使用します。

(***) ゼロを暗号化する理由は、カーネルがすべての数のゼロに対して高性能データソースを提供するためです。それ以外の場合、他の暗号化モードも同じように機能します。

おすすめ記事