メインコンテンツ

予測可能なブロック暗号初期化ベクトル

初期化ベクトルを脆弱な乱数発生器から生成している

説明

この欠陥は、ブロック暗号初期化ベクトルに脆弱な乱数発生器を使用した場合に発生します。

リスク

脆弱な乱数発生器を使用して初期化ベクトルを生成すると、データは辞書攻撃に対して脆弱になります。

ブロック暗号は、データを固定サイズのブロックに分割します。CBC (Cipher Block Chaining) などのブロック暗号モードは、辞書攻撃から保護するために、各ブロックと前のブロックからの暗号化出力とを XOR 演算します。最初のブロックを保護するため、このようなモードではランダムな初期化ベクトル (IV) を使用します。IV に脆弱な乱数発生器を使用すると、データは辞書攻撃に対して脆弱になります。

修正方法

初期化ベクトルに強力な疑似乱数発生器 (PRNG) を使用します。たとえば、次を使用します。

  • UNIX®/dev/random や Windows®CryptGenRandom() など、OS レベルの PRNG

  • カウンター (CTR) モードでの高度暗号化標準 (AES)、HMAC-SHA1 など、アプリケーション レベルの PRNG

暗号法的に脆弱な疑似乱数発生器の一覧については、Vulnerable pseudo-random number generator を参照してください。

すべて展開する

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *key){
    unsigned char iv[SIZE16];
    RAND_pseudo_bytes(iv, 16);
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 
}

この例では、openssl/rand.h で宣言されている関数 RAND_pseudo_bytes によって初期化ベクトルを生成しています。RAND_pseudo_bytes が生成するバイト シーケンスは、必ずしも予測不可能ではありません。

修正 — 強力な乱数発生器を使用

強力な乱数発生器を使用して初期化ベクトルを作成します。修正した次のコードでは、openssl/rand.h で宣言されている関数 RAND_bytes を使用します。


#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *key){
    unsigned char iv[SIZE16];
    RAND_bytes(iv, 16);
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 
}

結果情報

グループ: 暗号化
言語: C | C++
既定値: オフ
コマンド ライン構文: CRYPTO_CIPHER_PREDICTABLE_IV
影響度: Medium

バージョン履歴

R2017a で導入