[解決済み] エラー「java.security.InvalidKeyException」の原因は何ですか?Parameters missing "というエラーは何ですか?[重複しています]。
2022-03-04 21:27:06
質問事項
AESを使って文字列を暗号化・復号化しようとしているのですが、解決方法がわからないエラーが発生します。これはコードです。
public class EncryptionTest{
public static void main(String[] args) {
String encrypt = new String(encrypt("1234567890123456"));
System.out.println("decrypted value:" + (decrypt("ThisIsASecretKey",encrypt)));
}
public static String encrypt(String value) {
try {
byte[] raw = new byte[]{'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string:" + (new String(encrypted)));
return new String(skeySpec.getEncoded());
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key, String encrypted) {
try {
SecretKeySpec skeySpec = new SecretKeySpec(Base64.decodeBase64(key), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(skeySpec.getEncoded(),"AES"));
(*)
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
original.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
実行すると、"decription"の値がnullになります。(***)の前に失敗します!
例外が発生します。
java.security.InvalidKeyException: パラメータがありません at com.sun.crypto.provider.CipherCore.init(CipherCore.java:388) at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:186) at javax.crypto.Cipher.implInit(Cipher.java:787) at javax.crypto.Cipher.chooseProvider(Cipher.java:849) at javax.crypto.Cipher.init(Cipher.java:1213) at javax.crypto.Cipher.init(Cipher.java:1153) at firma.XmlEncryptionTest.decrypt(EncryptionTest.java:63) at firma.XmlEncryptionTest.main(EncryptionTest.java:41)
ここで、63行目は、その前の行です(***)。何が間違っているのか、どうすれば解決するのかわかりません。インターネットでいろいろ調べてみましたが、何が足りないパラメータなのか分かりませんでした。
どのように解決するのですか?
あなたのコードの主な問題は、IV 値の指定に失敗したことに起因しています。CBCモードの暗号化を行う際にはIV値を指定し、CBCモードの復号化を行う際にはその同じ値を使用する必要があります。
また、バイト配列からの文字列作成とbase64エンコーディングが混在していることも問題です。また
null
を毎回 decrypt メソッドから実行しています。たとえ
return original.toString();
というのは、まだ間違っています。
toString()
は、バイト配列の場合、あなたが望むようなことはできません)。
以下は、あなたのコードの改良版です。最適とは程遠いですが、コンパイルして動作します。ランダムIVを使用するために、これを改良する必要があります。 また、パスワードから鍵を導出する場合は、単にバイトを取得するだけでなく、PBKDF2などの導出関数を使用するようにしましょう . PBKDF2 を使用した例を JNCryptorソース .
public class EncryptionTest {
public static void main(String[] args) {
try {
String key = "ThisIsASecretKey";
byte[] ciphertext = encrypt(key, "1234567890123456");
System.out.println("decrypted value:" + (decrypt(key, ciphertext)));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String key, String value)
throws GeneralSecurityException {
byte[] raw = key.getBytes(Charset.forName("UTF-8"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec,
new IvParameterSpec(new byte[16]));
return cipher.doFinal(value.getBytes(Charset.forName("UTF-8")));
}
public static String decrypt(String key, byte[] encrypted)
throws GeneralSecurityException {
byte[] raw = key.getBytes(Charset.forName("UTF-8"));
if (raw.length != 16) {
throw new IllegalArgumentException("Invalid key size.");
}
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec,
new IvParameterSpec(new byte[16]));
byte[] original = cipher.doFinal(encrypted);
return new String(original, Charset.forName("UTF-8"));
}
}
関連
-
[解決済み】指定された子にはすでに親がいます。先に子の親に対してremoveView()を呼び出す必要がある(Android)
-
[解決済み】Mockitoでモックからチェックされた例外を投げる
-
[解決済み】なぜjava.io.Fileにはcloseメソッドがないのでしょうか?
-
[解決済み】java 'jar'が内部コマンドまたは外部コマンドとして認識されない。
-
[解決済み】スレッド "main "での例外 java.util.NoSuchElementException
-
[解決済み】予期しない型エラー
-
[解決済み] エラー - trustAnchors パラメータは空であってはなりません。
-
[解決済み] JVM起動時のパラメータ「-Xms」「-Xmx」とは何ですか?
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] if / for / while 内で "Missing return statement" が発生する。
-
[解決済み】Android Studio クラス org.codehaus.groovy.runtime.InvokerHelper を初期化できませんでした。
-
[解決済み】エラー:配列または java.lang.Iterable のインスタンスに対してのみ反復処理を行うことができます。
-
[解決済み] hibernateでResultSetを抽出できない。
-
[解決済み】エラー。Selection does not contain a main type
-
[解決済み】"比較メソッドはその一般契約に違反する!"
-
[解決済み】宣言されたパッケージが期待されるパッケージと一致しない ""
-
[解決済み] hibernate のプロパティが見つかりません。
-
[解決済み] [Solved] java.lang.NoClassDefFoundError: クラスXXXを初期化できませんでした。
-
[解決済み] "java.nio.charset.MalformedInputException" を避けるために、すべての包括的なCharset。入力の長さ= 1"?