メインコンテンツ

暗号化の最終ステップがありません

データの暗号化または復号化の更新ステップ後に最終ステップを実行していない

説明

この欠陥は、データの暗号化または復号化の更新ステップ後に最終ステップを実行しなかった場合に発生します。

たとえば、次を行います。

/* Initialization of cipher context */
ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
...
/* Update step */
ret = EVP_EncryptUpdate(&ctx, out_buf, &out_len, src, len);
...
/* Missing final step */
...
/* Cleanup of cipher context */
EVP_CIPHER_CTX_cleanup(ctx);

リスク

ブロック暗号は、データを固定サイズのブロックに分割します。暗号化または復号化時は、更新ステップでブロック内のデータの暗号化または復号化が行われます。最終ステップでは、残りのデータがある場合にそのデータの暗号化または復号化が行われます。最終ステップでは、1 ブロックが埋まるように残りのデータにパディングが追加され、パディング後のデータの暗号化または復号化が行われます。

最終ステップを実行しないと、部分ブロック内の残りのデータが暗号化または復号化されません。不完全な出力や、予期しない出力になる可能性があります。

修正方法

暗号化または復号化の更新ステップの後に、最終ステップを実行して残りのデータを暗号化または復号化します。

/* Initialization of cipher context */
ret = EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
...
/* Update step(s) */
ret = EVP_EncryptUpdate(&ctx, out_buf, &out_len, src, len);
...
/* Final step */
ret = EVP_EncryptFinal_ex(&ctx, out_buf, &out_len);
...
/* Cleanup of cipher context */
EVP_CIPHER_CTX_cleanup(ctx);

すべて展開する


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

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(unsigned char *src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Update steps for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);   
    
    /* Missing final encryption step */
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

この例では、暗号化の最終ステップの前に暗号コンテキスト ctx をクリーンアップしています。最終ステップは、残りのデータを暗号化しなければなりません。最終ステップを実行しないと、暗号化は不完全になります。

修正 — 暗号化の最終ステップを実行

暗号化の更新ステップの後に、暗号化の最終ステップを実行して残りのデータを暗号化します。修正した次のコードでは、ルーチン EVP_EncryptFinal_ex が最終ステップを実行します。


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

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(unsigned char *src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Update steps for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);   
    
    /* Final encryption step */
    EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

結果情報

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

バージョン履歴

R2017a で導入