0

DESfire EV1タグと対話する場合、通信を保護するためにAES-CBCが使用されます。メッセージを暗号化して送信した後、暗号化の結果であるIVを使用して応答を復号化する必要があります。

Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(zeroBytes));

byte[] encrypted_response = transceive(c.doFinal(message));

// TODO: cipher needs to be re-set to DECRYPT_MODE while retaining the IV
c.init(Cipher.DECRYPT_MODE, ...?);

byte[] response = c.doFinal(encrypted_response);

残念ながら、Cipher.getIV()は最初のIV(すべてゼロ)を返し、CBC部分全体を手動で実装する以外にIVを取得する方法はないようです。バイトを暗号化した後に暗号から更新されたIVを取得するでは、同様の質問が行われますが、CBCモードには適用されないCTR固有のソリューションのみが示されています。

4

2 に答える 2

2

ここでは、暗号化IVをすべてゼロに設定します。

new IvParameterSpec(zeroBytes)

したがって、代わりにランダムバイトを使用し、それらのランダムバイトをivとして使用する場合は、自分でそれらを追跡します。

アップデート

コメントから、復号化の途中または途中のチャンクを再開しようとしているようです。CBCモードでは、ストリームまたはチャンクでブロック整列されている限り、前の暗号文のブロックをIVとして使用できます。

于 2013-03-25T13:25:17.817 に答える
0

Cipherを呼び出すことにより、オブジェクトからIVを取得できますc.getIV()。これにより、IVデータを含むバイト配列が返されます。次に、それを復号化側のIVParametersSpecにプラグインできます。

とはいえinit、暗号化の方法を誤って使用しています。呼び出しでIVParameterSpecを指定した場合、(他の回答のコメントで言うように)内部IVは生成されませんinit。代わりに、すべてゼロのIVを使用します。これは、そのバージョンが実行するように init指示しているためです。代わりに、呼び出しを使用してinitのようc.init(Cipher.ENCRYPT_MODE, secretKey)にし、上記c.getIV()を使用してIVを取り出します。ここでCipherのjavadocsをチェックして、私が何を意味するかを確認してください。

于 2013-03-25T19:00:47.250 に答える