文字列を復号化しようとしています"~9?8?m???=?T?G"
OpenSSLを使用してAES-256-CBCを使用して文字列を暗号化するバックエンドサーバーから受信します。コードブロックがあります:
public static String decryptText(String textToDecrypt) {
try {
byte[] base64TextToDecrypt = Base64.encodeBase64(textToDecrypt.getBytes("UTF-8"));
byte[] guid = "fjakdsjkld;asfj".getBytes("UTF-8");
byte[] iv = new byte[16];
System.arraycopy(guid, 0, iv, 0, guid.length);
IvParameterSpec ips = new IvParameterSpec(iv);
byte[] secret = DECRYPTION_SECRET_HASH.getBytes("UTF-8");
SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, secretKey, ips);
byte[] converted = cipher.doFinal(base64TextToDecrypt);
System.out.println(new String(converted));
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Decipher error for " + textToDecrypt, e);
}
return "";
}
残念ながら、
byte[] converted = cipher.doFinal(base64TextToDecrypt);
次の例外がスローされます。
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
何か案は?
メソッドの開始時に、文字列のプラットフォーム固有の表現をエンコードする代わりに、文字列をデコードする必要があります。
_byte[] base64TextToDecrypt = Base64.decodeBase64(textToDecrypt);
_
またはより正確に:
_byte[] bytesToDecrypt = Base64(base64TextToDecrypt);
_
変数に正しく名前を付ければ。
一般に、(必要に応じて)String.getBytes(): byte[]
メソッドまたはString(byte[])
コンストラクターを使用するたびに、何か間違ったことをしている可能性があります。最初に何をしようとしているのかを考え、doを使用する必要がある場合は、 文字エンコード を指定する必要があります。
あなたの場合、converted
変数の出力はおそらく文字エンコードされています。したがって、次のフラグメントを使用できます。
_String plainText = new String(converted, StandardCharsets.UTF_8);
System.out.println(plainText);
_
あなたが今持っているものの代わりに。
@owlsteadのおかげで、私は解決策を見つけることができました。すでにBase64でエンコードされた文字列をBase64でエンコードするのを間違えたのです。以下はコードチャンクによるものです。
public static String decryptText(String textToDecrypt) {
try {
byte[] decodedValue = Base64.decodeBase64(textToDecrypt.getBytes());
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ips = new IvParameterSpec(iv);
byte[] input = textToDecrypt.getBytes();
Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, ips);
byte[] plainText = cipher.doFinal(decodedValue);
return new String(plainText);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Decipher error for " + textToDecrypt, e);
}
return "";
}
対応する暗号化は次のようになります
public static String encryptText(String textToEncrypt) {
try {
byte[] guid = "1234567890123456".getBytes("UTF-8");
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ips = new IvParameterSpec(iv);
// The secret key from the server needs to be converted to byte array for encryption.
byte[] secret = ENCRYPTION_SECRET_HASH.getBytes("UTF-8");
// we generate a AES SecretKeySpec object which contains the secret key.
// SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");
Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);
cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, ips);
byte[] cipherText = cipher.doFinal(textToEncrypt.getBytes());
byte[] base64encodedSecretData = Base64.encodeBase64(cipherText);
String secretString = new String(base64encodedSecretData);
return secretString;
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Encryption error for " + textToEncrypt, e);
}
return "";
}