2016-06-27 13 views
3

私は、Java CardでRSA公開鍵を使用して10バイトの乱数を暗号化するプログラムを作成しました。乱数はカードがそのAPDUコマンドを受け取るたびに生成され、私のアプレットでは関連する暗号オブジェクトのブロックサイズが2048ビットなので0x00の242バイトをこの10バイトの乱数の末尾に付加して256バイトにします長さRSA EncrytionがJavaCardで断続的に例外をスローする

場合によっては、応答が05の値を持つ暗号例外であることが問題です。あなたが知っていると述べたJCのAPIドキュメントのように:

0x05 = ILLEGAL_USE

のpublic static final短いILLEGAL_USEが

この理由コードは、 に使用された署名や暗号アルゴリズムがないことを示しています入力メッセージが に埋め込まれ、入力メッセージがブロック位置合わせされていない。

入力長が自分のアプレットで固定されているため、問題を解決できません。ここで

は私のアプレットの関連部分です:

protected final void getEncChallenge(APDU apdu) { 
     random.generateData(generatedChall, (short) 0, (short) 10); 
     initAsymCipher(ENTITY_BOB, MODE_ENC); 
     Util.arrayCopy(generatedChall, (short) 0, transientData, (short) 0, (short) 10); 
     Util.arrayFillNonAtomic(transientData, (short) 10, (short) 246, (byte) 0x00); 
     rsaCrypto(transientData, persistentData); 
     apdu.setOutgoing(); 
     apdu.setOutgoingLength((short) 256); 
     apdu.sendBytesLong(persistentData, (short) 0, (short) 256); 
    } 

protected final void rsaCrypto(byte[] inData, byte[] outData) { 
    try{ 
     asymCipher.doFinal(inData, (short) 0, (short) 256, outData, (short) 0); 
    }catch(CryptoException e){ 
     short reason = e.getReason(); 
     ISOException.throwIt((short)(0x6d00 | reason)); 
    } 
} 

そして、ここでは、応答である:

transientData ---> APDU Response 
--------------------------------- 
80 ..(Eight Random Bytes).. BD ..(246 bytes of "0x00").. ---> OK (i.e. 256 byte encrypted data) 
EO ..(Eight Random Bytes).. 64 ..(246 bytes of "0x00").. ---> 6D05 
02 ..(Eight Random Bytes).. B3 ..(246 bytes of "0x00").. ---> OK 
CB ..(Eight Random Bytes).. 35 ..(246 bytes of "0x00").. ---> 6D05 
17 ..(Eight Random Bytes).. 97 ..(246 bytes of "0x00").. ---> OK 
0C ..(Eight Random Bytes).. 0C ..(246 bytes of "0x00").. ---> OK 
D3 ..(Eight Random Bytes).. 91 ..(246 bytes of "0x00").. ---> 6D05 
86 ..(Eight Random Bytes).. E2 ..(246 bytes of "0x00").. ---> OK 
C2 ..(Eight Random Bytes).. 23 ..(246 bytes of "0x00").. ---> 6D05 

誰もが私のアプレットと間違って何任意のアイデアを持っていますか?

+0

どのようなALG_をお使いですか? – vojta

+0

@vojta 'asymCipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD、false); ' – Abraham

答えて

3

あなたは間違った側でパディングしています。 RSAはビッグエンディアンで符号化された数値をモジュラスサイズまで処理します。通常のパディングメカニズム(通常のRSAセキュリティに必要)は、の左にのパディングを施し、モジュラスよりも厳密に小さい値にします。

基本的には、埋め込まれたチャレンジはエンコードされた数字とみなされ、変換されたときには時々モジュラスよりも大きくなります。それが起こると、RSAルーチンはそれを受け入れません。

左にゼロバイトを埋め込むことでこれが解決されます。あるいは、チャレンジの最上位ビットが0にマスクされていることを確認することもできます(& 0x7F)。

+0

親愛なるMr Bodewesさんありがとうございます。私は少し混乱しています。もう少し説明してもらえますか?私はアルゴリズムがALG_RSA_NOPADであることを示していると思いますが、暗号はチャレンジをパディングまたはエンコードされたデータではなく256バイトのデータとして見なければなりません。右?では、なぜ変換があるのですか?あなたの答えは、ALG_RSA_NOPADは、256バイトのデータのいくつかの形式を暗号化できないことを意味しますか? – Abraham

+0

あなたはどの変換を意味するのですか?そして変換されたとき、時には...? – Abraham

+1

はい、ALG_RSA_NOPADはそれを実行できません。理由は簡単です。モジュラスより高い数値でモジュラー演算を実行すると、明らかに値は(この場合) 'number - N'として扱われます。ですから、あなたがそれを元に戻すと、 'number'の代わりに' number - N'も得られます。これはRSAの基本的な問題です。もちろん、デコードされた数字が実際どれだけ大きいかという挑戦にも依存します。 'FF'ヘキサで始まる場合、それはモジュラスよりも確かに大きいです。 '7F' hexまたはそれ以下で始まる場合は、より小さくなければなりません(モジュラスの最上位ビットが常にセットされます)(これを試してください)。 –

関連する問題