OpenSSL または Crypto++ ライブラリを使用して暗号ナンスを生成する方法があるかどうか疑問に思っています。自動シードされたプールを使用して一連のランダム バイトを生成する以外に何かありますか?
3 に答える
OpenSSL または Crypto++ ライブラリを使用して暗号ナンスを生成する方法があるかどうか疑問に思っています。
暗号++ :
SecByteBlock nonce(16);
AutoSeededRandomPool prng;
prng.GenerateBlock(nonce, nonce.size());
OpenSSL :
unsigned char nonce[16];
int rc = RAND_bytes(nonce, sizeof(nonce));
unsigned long err = ERR_get_error();
if(rc != 1) {
/* RAND_bytes failed */
/* `err` is valid */
}
/* OK to proceed */
自動シードされたプールを使用して一連のランダム バイトを生成する以外に何かありますか?
nonce は基本的に IV です。通常、IV やソルトなどのパブリック パラメータと見なされます。
nonce は、セキュリティ コンテキスト内で一意である必要があります。予測できないようにするためにノンスも必要になる場合があります。
一意性と予測不可能性は、2 つの異なる特性です。たとえば、で始まるカウンター0000000000000000
は一意ですが、予測可能でもあります。
一意性と予測不能性の両方が必要な場合は、ノンスをランダムな値とカウンターに分割できます。ランダム値は、16 バイトの nonce の 8 バイトを占めます。一方、カウンタは 16 バイトの nonce の残りの 8 バイトを使用します。次に、インクリメント関数を使用してi++
、値が必要になるたびに基本的に実行します。
8 対 8 の分割は必要ありません。12-4 は 4-12 と同様に機能します。これは、アプリケーションと、キーを再生成する前に必要な nonce の数によって異なります。通常、キーの再生成はプレーン テキストのバイト カウントによって行われます。
16-0 も機能します。この場合、ランダムな値を使用し、カウンターを避け、インクリメント関数を避けています。(インクリメント関数は基本的にカスケード加算です)。
NIST SP800-38CとSP800-38Dは、CCM と GCM が使用するナンスを作成するためのいくつかの方法を提供します。
ノンスの要件は何ですか?も参照してください。暗号スタック交換で。
いいえ。nonce が十分に大きい場合は、自動シードされた DRBG (決定論的ランダム ビット ジェネレーター - NIST 命名法) で問題ありません。約 12 バイトの nonce をお勧めします。nonce を 16 バイトにする必要がある場合は、互換性を最大限に高めるために、最下位ビット (ほとんどの場合は右端のバイト) をゼロに設定しておくことができます。
API によって提供される暗号的に安全な乱数ジェネレーターを使用するだけで問題ありません。オペレーティング システムから取得した情報 (おそらく他のデータの中で) を使用してシードする必要があります。念のため、シード データにシステム時間を追加しても問題はありません。
別の方法として、シリアル番号を使用することもできますが、その場合、呼び出し全体で困難な状態を維持する必要があります。時計が繰り返される可能性がある多くの落とし穴があることに注意してください (夏時間、OS の変更、バッテリー切れなど)。
乱数ジェネレーターが十分な大きさの出力を繰り返さないことを再確認することは決して悪いことではありません。たとえば、Debian の静的コード分析後の修正により、OpenSSL RNG がまったくシードされなかった場合など、プログラミングまたはシステム構成の誤りだけで問題が発生しています。