opensslコマンドで暗号化された文字列をJavaで復号したい
#前提・実現したいこと
PostgreSQLのDBに、Pythonツールで暗号化したパスワードが格納されています。
JavaでそのパスワードをDBから取得し、復号して平文に戻したいです。
Pythonツールでは以下、Linuxコマンドのopensslを使って暗号化しています。
Base64 =============================================================================== [root]# echo "hoge" | openssl enc -e -des -base64 -k "test" U2FsdGVkX196J+27IM+QRwos2qbm9tpu ===============================================================================
Linux上でコマンドを使用すれば複合できることは確認しています。
=============================================================================== [root]# echo "U2FsdGVkX196J+27IM+QRwos2qbm9tpu" | openssl enc -d -des -base64 -k "test" hoge ===============================================================================
#環境
- Eclipse IDE for Enterprise Java Developers.
Version: 2019-12 (4.14.0)
- OS windows8(64bit)
- JavaSE 1.8
- Springboot
開発は上記Windows環境で実施していますが、最終的にはwarにしてLinuxで動かします。
#作成したJavaソース
以下が私が作成したJavaのソースになります。
暗号にはECBモード,CBCモードなどがあるようですが、OpenSSLで暗号化した場合どのモードを使用すればよいかもよくわかっていません。
以下ではECBを使用しています。
java
1package com.example.demo; 2 3import java.util.Base64; 4 5import javax.crypto.Cipher; 6import javax.crypto.spec.SecretKeySpec; 7 8public class test { 9 10 public static void main(String[] args) throws Exception { 11 12 //キー 13 String key = "test"; 14 //複号対象文字列 15 String enc = "2FsdGVkX196J+27IM+QRwos2qbm9tpu"; 16 17 18 byte[] enc_decode = Base64.getDecoder().decode(enc.getBytes()); 19 20 SecretKeySpec skey = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 21 22 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 23 cipher.init(Cipher.DECRYPT_MODE, skey); 24 byte[] decrypted = cipher.doFinal(enc_decode); 25 26 System.out.println(decrypted); ←ここで「hoge」と出てほしい 27 } 28} 29 30 31
#実行結果
上記のソースを実行すると、エラーがでます。
Springbootのフレームワークを使用しており、Springスタータープロジェクトの配下に作成したクラスのためSpringBootアプリケーションから実行した結果です。
Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 4 bytes
at java.base/com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:90) at java.base/com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:95) at java.base/com.sun.crypto.provider.CipherCore.init(CipherCore.java:591) at java.base/com.sun.crypto.provider.CipherCore.init(CipherCore.java:467) at java.base/com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:313) at java.base/javax.crypto.Cipher.implInit(Cipher.java:839) at java.base/javax.crypto.Cipher.chooseProvider(Cipher.java:901) at java.base/javax.crypto.Cipher.init(Cipher.java:1286) at java.base/javax.crypto.Cipher.init(Cipher.java:1223) at com.example.demo.test.main(test.java:23)
「Invalid AES key length:」をGoogle検索して関係ありそうな以下も試してみましたが、効果はありませんでした。
- C:\pleiades\java\8\jre\lib\security\java.security
→ 「crypto.policy=unlimited」のコメントを外して有効にする
参考:ttps://itdogkuwaccho.hatenadiary.com/entry/2017/11/12/125140
以上、よろしくお願いします。
##2020/2/17追記
DES形式でソースを修正しました。
java
1 public static void main(String[] args) { 2 3 String key = "foobar00"; 4 String origin = "hoge"; 5 String enc = "U2FsdGVkX19eAkcLovbInztwfaMnjKwZ"; 6 7 8 try { 9 /* 10 * 鍵 11 */ 12 // 秘密鍵を準備 13 byte[] kagi = key.getBytes(); 14 DESKeySpec dk = new DESKeySpec(kagi); 15 Arrays.fill(kagi, (byte)0x00); // セキュリティ情報を上書きして削除 16 SecretKeyFactory kf = SecretKeyFactory.getInstance("DES"); 17 SecretKey sk = kf.generateSecret(dk); 18 19 20 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 21 cipher.init(Cipher.DECRYPT_MODE, sk); 22 Cipher c = Cipher.getInstance("DES"); 23 24 //暗号化されたStringをデコード 25 byte[] enc_decode = Base64.getDecoder().decode(enc.getBytes()); 26 27 //復号 28 byte[] output2 = c.doFinal(enc_decode); 29 30 31 // 表示 32 System.out.println("The string was "); 33 System.out.println(new String(output2)); 34 35 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 } 40
#実行結果
上記のソースを実行すると、下記エラーがでます。
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975) at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056) at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853) at java.base/com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314) at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202) at com.example.demo.test2.main(test2.java:133)
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/18 09:02