現在下記仕様でパラメータの暗号化複合化処理を作成していますが例外が発生して困っています。
方式:DES
モード:CBC
パディング:PKCS5Padding
秘密鍵:kagi1234
BASE64でエンコードしてString変換
【例外内容】
Exception in thread "main" java.lang.RuntimeException: java.security.InvalidKeyException: Parameters missing
at enc.Main01.decrypt(Main01.java:114)
【ソースコード】
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
public class Main01 {
public static void main(String[] args) {
try {
String val1 = encrypt("10000", "key12345");
System.out.println(decrypt(val1, "key12345"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String text, String secretKey) throws Exception {
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "DES");
Cipher cp = Cipher.getInstance("DES/CBC/PKCS5Padding");
cp.init(Cipher.ENCRYPT_MODE, sks);
return new BASE64Encoder().encodeBuffer(cp.doFinal(text.getBytes()));
}
public static String decrypt(String decValue, String secretKey) throws Exception {
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "DES");
byte[] decArr = new sun.misc.BASE64Decoder().decodeBuffer(decValue);
Cipher cp = Cipher.getInstance("DES/CBC/PKCS5Padding");
cp.init(Cipher.DECRYPT_MODE, sks);
return new String(cp.doFinal(decArr));
}
}
対処方法がも解らず自力解決は困難です。
お手数ですが解決方法を御教授願えないでしょうか?
よろしくお願いします。
環境(WidowsXP SP2, JDK1.5.0_07-b03)
No.1
- 回答日時:
Sunのサンプルコードを見ると、
暗号化に使ったSecurityAlgorithmParametersを、復号に使う必要があります。ENCRYPT_MODEでinitした際に暗黙的に生成されてるみたい。
質問文のコードを改変したもの(☆が追加):
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters; /* ☆ */
import sun.misc.BASE64Encoder;
public class Main01 {
private static byte[] enc_param_; /* ☆ */
public static void main(String[] args) {
try {
String val1 = encrypt( args[0], "key12345");
System.out.println(val1);
System.out.println(decrypt(val1, "key12345"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String encValue, String secretKey) throws Exception {
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "DES");
Cipher cp = Cipher.getInstance("DES/CBC/PKCS5Padding");
cp.init(Cipher.ENCRYPT_MODE, sks);
enc_param_ = cp.getParameters().getEncoded(); /* ☆ */
return new BASE64Encoder().encodeBuffer(cp.doFinal(encValue.getBytes()));
}
public static String decrypt(String decValue, String secretKey) throws Exception {
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "DES");
Cipher cp = Cipher.getInstance("DES/CBC/PKCS5Padding");
AlgorithmParameters saprm = AlgorithmParameters.getInstance("DES"); /* ☆ */
saprm.init( enc_param_ ); /* ☆ */
cp.init(Cipher.DECRYPT_MODE, sks, saprm /* ☆ */ );
byte[] decArr = new sun.misc.BASE64Decoder().decodeBuffer(decValue);
return new String(cp.doFinal(decArr));
}
}
この回答への補足
osamuy様
早速の回答ありがとうございます。
いただいたソースを実行してみましたが、無事暗号、複合化を行なうことができました。
ただ、実行する度に暗号化した文字列が異なってしまいます。
これは回避不能なのでしょうか?
実は今回、秘密鍵を使用してパラメータを暗号化し、拠点Aと拠点BでHTTPで通信を行なう必要があります。
秘密鍵はお互いの外部ファイルに保持していますので、その鍵を使用して暗号、復号できればと考えているのです。
この場合、同じ秘密鍵を使用して暗号化したならば、必ず同じ暗号になりませんと送信先で復号できないと思っています。
DESを使用した暗号化/複合化の場合、秘密鍵をお互い保持しておくだけでなく
今回osamuy様追加した変数の「enc_param_」も送信先に引き継がなければならないのでしょうか?
≪いただいたソースの実行結果≫
引数に「10000」を指定
【1回目】
暗号化後:6wc4lWqk4XI=
複合化後:10000
【2回目】
暗号化後:I58cD3SogT4=
複合化後:10000
【3回目】
暗号化後:w536VsFvHJY=
複合化後:10000
No.2ベストアンサー
- 回答日時:
> ただ、実行する度に暗号化した文字列が異なってしまいます。
> 変数の「enc_param_」も送信先に引き継がなければならないのでしょうか?
多分YESです。
手っ取り早く、ソースにハードコードしといて、常に同じsecurity.AlgorithmParametersを使用する手もあります。
例)
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import sun.misc.BASE64Encoder;
public class code {
private final static String SECRET_PW = "key12345";
private final static byte[] enc_param_ = {4,8,-9,98,88,-115,5,-124,-69,31};
public static void main(String[] args) {
try {
String val1 = encrypt( args[0], SECRET_PW );
System.out.println(val1);
System.out.println(decrypt( val1, SECRET_PW ));
} catch (Exception e) { e.printStackTrace(); }
}
private static Cipher setup_cipher( int ci_mode, String secretKey ) throws Exception {
SecretKeySpec sks = new SecretKeySpec(secretKey.getBytes(), "DES");
AlgorithmParameters saprm = AlgorithmParameters.getInstance("DES");
saprm.init( enc_param_ );
Cipher cp = Cipher.getInstance("DES/CBC/PKCS5Padding");
cp.init( ci_mode, sks, saprm );
return cp;
}
public static String encrypt(String encValue, String secretKey) throws Exception {
Cipher cp = setup_cipher( Cipher.ENCRYPT_MODE, secretKey );
return new BASE64Encoder().encodeBuffer(cp.doFinal(encValue.getBytes()));
}
public static String decrypt(String decValue, String secretKey) throws Exception {
Cipher cp = setup_cipher( Cipher.DECRYPT_MODE, secretKey );
byte[] decArr = new sun.misc.BASE64Decoder().decodeBuffer(decValue);
return new String(cp.doFinal(decArr));
}
}
>実は今回、秘密鍵を使用してパラメータを暗号化し、拠点Aと拠点BでHTTPで通信を行なう必要があります。
だったら、SSLを使う方が簡単では。
No.3
- 回答日時:
>ただ、実行する度に暗号化した文字列が異なってしまいます。
回答ではありませんが、CBCモードについていま一度勉強されてみてはいかがでしょうか?
参考サイトを参考にしてください。
参考URL:http://www.ss.iij4u.or.jp/~somali/web/_block_mod …
ご回答ありがとうございます。
下記の記述でProviderを追加するようにした所
毎回同じ値を作成することができました。
Security.addProvider(new com.sun.crypto.provider.SunJCE());
回答をしてくださったみなさま
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java java final 1 2022/06/10 22:49
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java 直し方について教えて頂きたいです。 4 2022/08/13 02:11
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数を動的に利用するには?
-
NoSuchMethodErrorが解決できま...
-
中カッコ{}だけの記述について
-
【初心者です】javaで平均値を...
-
System.exit()の値を取得したい
-
randomで
-
ArrayList でスタックを
-
インタフェイス実装と抽象クラ...
-
getActualMaximum(Calendar.DAY...
-
Javaでlog4jを使ってログ出力を...
-
java 継承の問題で分からないと...
-
Socketの接続のタイムアウトを...
-
GetterとSetterをやったのに。
-
Java 最大公約数 gcd
-
コマンドライン引数の*(アフ...
-
プログラミングの問題です。大...
-
コンストラクタ,interface,abst...
-
元旦からの経過日数を求めたい
-
コンパイラのバグ?それとも
-
元旦からの日数を入力して、何...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミングの問題です。大...
-
変数を動的に利用するには?
-
中カッコ{}だけの記述について
-
System.exit()の値を取得したい
-
Javaでlog4jを使ってログ出力を...
-
NoSuchMethodErrorが解決できま...
-
javaで特定の文字列から特定の...
-
Socketの接続のタイムアウトを...
-
Java プログラム public class ...
-
javaのプログラミングで作るRPG...
-
インタフェイス実装と抽象クラ...
-
コマンドライン引数の*(アフ...
-
【初心者です】javaで平均値を...
-
Javaで日本語の出力が文字化けする
-
(大至急)JavaでATMもどきを作成
-
コンストラクタの引数の中のnew?
-
Java 最大公約数 gcd
-
C# DatagridviewにExcelシート...
-
randomで
-
GetterとSetterをやったのに。
おすすめ情報