2017-03-06 12 views
2

次の例では、RSA 256-bitprivate keyを使用して、パディングなしで32バイトメッセージを暗号化し、同じメモリブロックに結果を格納します。RSA_private_encryptの可能性のあるバグ

#include <openssl/ssl.h> 
unsigned char err[256], 
       msg[] = "This is a message of some sort.", 
       key[] = "-----BEGIN RSA PRIVATE KEY-----\n"\ 
"MIGrAgEAAiEA6sZFpHqqFkpskc2GNMl6RHdiEuOqlX3LcW1TnYVgQFECAwEAAQIh\n"\ 
"AKqoe8FHJVJUwTzvMAo5FrU/t6Cc6GwYDELpU3xxs4nBAhEA+TwHM5ArwBgTtB2y\n"\ 
"AKlEKQIRAPElwlKWyde1KqHRCjOWX+kCEQDqWYZP9rUcp8cHKpDwTDiZAhBPldOd\n"\ 
"KDCzJRJN10yTm/RJAhANYsX4BteC/W7VRUjV5jSH\n"\ 
"-----END RSA PRIVATE KEY-----\n"; 
void main() 
{ 
    //msg[0] = 255; 
    if (RSA_private_encrypt(32, msg, msg, 
    PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(key, -1), NULL, NULL, NULL), 
    RSA_NO_PADDING) != 32) 
    { 
     ERR_load_crypto_strings(); 
     ERR_error_string(ERR_get_error(), err); 
     puts(err); 
    } 
} 

私たちがコメントを除去することにより、0番目のメッセージ文字の値を変更すると、暗号化はメッセージで失敗します。

rsa routines:RSA_EAY_PRIVATE_ENCRYPT:data too large for modulus 

注非常に短いRSAキーとハードコーディングされたメッセージの長さがその問題を示すためだけに使用されます。キーはopensslバイナリを使用して生成され、functionは異なるサイズのキーでも失敗します(4096ビットのキーの場合は、the msg[0] = 192が原因)。

RSA_NO_PADDINGが明示的に指定されていても、関数が長さ記述子としてメッセージの先頭を解釈しているようです。これはバグですか?

+1

あなたは256ビットモジュラスを持っておらず、255.875ビットモジュラスを持っています。 –

答えて

5

RSAでは、モジュラス配列とデータ配列は大きな整数として解釈されます。データ整数はモジュラス整数より小さくなければなりません。そうしないと、暗号化された値を復元できません。

private keyをデコードしました。モジュラスの最初のバイトは0xEAです。つまり、署名したデータは、0xEA(234)より大きいバイトで始めることはできません。 msg[0] = 235;を指定すると、エラーに再びなります。

これは、パディングの原因となります。パディングされたデータの最初のバイトは通常0x00(またはパディングスキームによっては0x0001)でもあり、パディングされたデータがモジュラスよりも大きくなることはありません。

だから、あなたはバグを見つけられませんでした。あなたはちょうど暗号を間違って使用しています。私はメッセージに署名するためにいくつかのより高いレベルのAPIを使用することをお勧めします。


RSAではパディングが重要であることに注意してください。それがなければ、平文または偽造署名を回復する方法があります。暗号化にはOAEP、署名にはPSSを使用してください。また、鍵のサイズも重要です。今日では、4096ビットのキーを使用する必要があります。 256ビットのキーは、現在のスマートフォンではおそらく壊れる可能性のあるおもちゃのサイズです。

+0

パディングが使用されていないときに平文を回復する方法を説明するソースを教えてください。 – Ulrik

+1

自分のものであっても、何らかのパディングが必要です。これは、任意のデータに対するパディングなしでは解決できません。パディングスキームにはオーバーヘッドがあることに注意してください。したがって、OAEPを使用する場合、モジュラスはデータよりも少なくとも42バイト大きくなければなりません。いくつかの解決策があるかもしれませんが、なぜこれを望んでいるのかによって、この質問の範囲が広がりすぎてしまいます。新しい質問には、なぜそれが必要なのかについての詳細を尋ねることをお勧めします。プログラミングに関連していない場合は、[crypto.se] –

関連する問題