Javaの暗号化・復号についてのメモ。(業務内容がわからないようにざっくりした書き方になってます)
- システムAで4桁の数字を公開鍵暗号[algorithm/mode/padding=RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024、2048)]で暗号化→BASE64エンコーディングした暗号化文字列を作成し、システムBに送る。
- システムBでは、暗号化文字列を復号して4桁の数字を取り出す。
システムAとBでそれぞれ同一の秘密鍵を使って暗号化文字列を作成し復号してみたところ、同一システム内では暗号化・復号が問題なくできました。
ところが、システムAで作成した暗号化文字列をシステムBで復号しようとしたらエラーとなりました。
その時のスタックトレースは以下です。(ベンダー名は●●●で潰してます。)
javax.crypto.BadPaddingException: Decryption error at com.●●●.crypto.provider.RSAPadding.f(Unknown Source) at com.●●●.crypto.provider.RSAPadding.unpad(Unknown Source) at com.●●●.crypto.provider.RSACipher.a(Unknown Source) at com.●●●.crypto.provider.RSACipher.engineDoFinal(Unknown Source) at javax.crypto.Cipher.doFinal(Unknown Source)
何やらPaddingのところでエラーが出てました。
システムAとBでそれぞれの同一システム内では暗号化・復号ができていることから、使用しているJavaの差異があやしいなと思って色々調べてました(面倒なので書くのは割愛)が、最終的には以下のコード修正(システムA)で解決しました。
よくわからないけど、JavaはRSA/ECB/OAEPWithSHA-256AndMGF1Paddingを指定してもSHA-1がデフォルトになっていて、明示的にSHA-256を指定してあげないといけないんですかねぇ。
修正内容
修正前
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); ︙ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
修正後
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); ︙ cipher.init(Cipher.ENCRYPT_MODE, publicKey, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));