私のアプリケーションでは、secretKeyを使用してデータを暗号化および復号化しています。そのために私はAESアルゴリズムを使用しています。しかし、復号化で例外が発生します。秘密鍵を使用してすでに暗号化されている3つの値のうちの1つです。
例外は:
Illegal Block Size Exception Input length must be multiple of 16 when decrypting with padded cipher.
以下は私のコードです:
関数からencyrpt値へ
public static String symmetricEncrypt(String text, String secretKey) {
BASE64Decoder decoder = new BASE64Decoder();
byte[] raw;
String encryptedString;
SecretKeySpec skeySpec;
BASE64Encoder bASE64Encoder = new BASE64Encoder();
byte[] encryptText = text.getBytes();
Cipher cipher;
try {
raw = decoder.decodeBuffer(secretKey);
skeySpec = new SecretKeySpec(raw, "AES");
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encryptedString = bASE64Encoder.encode(cipher.doFinal(encryptText));
}
catch (Exception e) {
e.printStackTrace();
return "Error";
}
return encryptedString;
}
値を復号化する関数
public static String symmetricDecrypt(String text, String secretKey) {
BASE64Decoder decoder = new BASE64Decoder();
BASE64Decoder base64Decoder = new BASE64Decoder();
Cipher cipher;
String encryptedString;
byte[] encryptText = null;
byte[] raw;
SecretKeySpec skeySpec;
try {
raw = decoder.decodeBuffer(secretKey);
skeySpec = new SecretKeySpec(raw, "AES");
encryptText = base64Decoder.decodeBuffer(text);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
encryptedString = new String(cipher.doFinal(encryptText));
} catch (Exception e) {
e.printStackTrace();
return "Error";
}
return encryptedString;
}
以下は私が暗号化および復号化している値です
String secretKey = "XMzDdG4D03CKm2IxIWQw7g==";
String value1= "ABCD";
String enctypedValue1= "3uweh4pzoVyH1uODQmVNJA==";
String enctypedValue2= "37PTC20w4DMZYjG3f+GWepSvAbEJUccMXwS/lXilLav1qM/PrCTdontw5/82OdC1zzyhDEsFVRGo rV6gXAQcm+Zai15hliiUQ8l8KRMtUl4=";
String value4= "20000";
/** Ecnryption and decryption of value1 **/
String encryptedValue1= symmetricEncrypt(value1, secretKey);
String decryptedValue1 = symmetricDecrypt(encryptedValue1, secretKey);
/** Decryption of enctypedValue1 **/
String decryptedValue2 = symmetricDecrypt(enctypedValue1, secretKey);
System.out.println(decryptedValue2);
/** Decryption of enctypedValue2 (Not decrypted)**/
String decryptedValue3 = symmetricDecrypt(enctypedValue2, secretKey);
System.out.println(decryptedValue3);
/** Ecnryption and decryption of value4 **/
String encryptedValue4= symmetricEncrypt(value4, secretKey);
String decryptedValue4 = symmetricDecrypt(encryptedValue4, secretKey);
テスト機能では、以下の3つのテストケースを記述しました。
EncryptionValue2を復号化すると、次の例外が発生します。
Illegal Block Size Exception Input length must be multiple of 16 when decrypting with padded cipher
以下は私がこれまでに導き出したものです。
問題のある値は、デコード中に問題があるようです。復号化できない81の長さの配列を返しますか?
この問題が発生した場合は、すべての値で発生しているはずです。
これは値固有の問題ですか、それともパディングに関連する問題ですか、それとも異なるブラウザ、異なるOSで異なる動作をする可能性がありますか?
私は問題なくコードを実行することができました。ただし、エンコード/デコードにはApacheのBase64を使用しました...おそらくBase64にバグがあります。自分で書いた場合、見逃してしまう可能性が高いです。実際の本番コードでは、Apacheなどの十分にテストされたライブラリを使用してください。
Base64で使用したライブラリはここにあります: http://commons.Apache.org/proper/commons-codec/download_codec.cgi
完全に機能するコードは次のとおりです。
package security.symmatric;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.Apache.commons.codec.binary.Base64;
public class AES {
public static String symmetricEncrypt(String text, String secretKey) {
byte[] raw;
String encryptedString;
SecretKeySpec skeySpec;
byte[] encryptText = text.getBytes();
Cipher cipher;
try {
raw = Base64.decodeBase64(secretKey);
skeySpec = new SecretKeySpec(raw, "AES");
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText));
}
catch (Exception e) {
e.printStackTrace();
return "Error";
}
return encryptedString;
}
public static String symmetricDecrypt(String text, String secretKey) {
Cipher cipher;
String encryptedString;
byte[] encryptText = null;
byte[] raw;
SecretKeySpec skeySpec;
try {
raw = Base64.decodeBase64(secretKey);
skeySpec = new SecretKeySpec(raw, "AES");
encryptText = Base64.decodeBase64(text);
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
encryptedString = new String(cipher.doFinal(encryptText));
} catch (Exception e) {
e.printStackTrace();
return "Error";
}
return encryptedString;
}
public static void main(String[] args) {
String secretKey = "XMzDdG4D03CKm2IxIWQw7g==";
String value1= "ABCD";
String enctypedValue1= "3uweh4pzoVyH1uODQmVNJA==";
String enctypedValue2= "37PTC20w4DMZYjG3f+GWepSvAbEJUccMXwS/lXilLav1qM/PrCTdontw5/82OdC1zzyhDEsFVRGo rV6gXAQcm+Zai15hliiUQ8l8KRMtUl4=";
String value4= "20000";
/** Ecnryption and decryption of value1 **/
String encryptedValue1= symmetricEncrypt(value1, secretKey);
String decryptedValue1 = symmetricDecrypt(encryptedValue1, secretKey);
System.out.println(decryptedValue1);
/** Decryption of enctypedValue1 **/
String decryptedValue2 = symmetricDecrypt(enctypedValue1, secretKey);
System.out.println(decryptedValue2);
/** Decryption of enctypedValue2 **/
String decryptedValue3 = symmetricDecrypt(enctypedValue2, secretKey);
System.out.println(decryptedValue3);
/** Ecnryption and decryption of value4 **/
String encryptedValue4= symmetricEncrypt(value4, secretKey);
String decryptedValue4 = symmetricDecrypt(encryptedValue4, secretKey);
System.out.println(decryptedValue4);
}
}