laz*_*pig 12 java encryption encoding aes character-encoding
我试图解密"~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 "";
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我到达时
byte[] converted = cipher.doFinal(base64TextToDecrypt);
Run Code Online (Sandbox Code Playgroud)
语句抛出以下异常:
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
您应该在方法的开头解码字符串,而不是编码字符串的平台特定表示.
byte[] base64TextToDecrypt = Base64.decodeBase64(textToDecrypt);
Run Code Online (Sandbox Code Playgroud)
或者更准确地说:
byte[] bytesToDecrypt = Base64(base64TextToDecrypt);
Run Code Online (Sandbox Code Playgroud)
如果你正确命名变量.
一般来说,每当你(觉得你必须)使用String.getBytes(): byte[]方法或String(byte[])构造函数时,你可能会做错事.你应该先想想你正在尝试做的,并指定一个字符编码,如果你也需要使用它.
在您的情况下,converted变量中的输出可能是字符编码的.所以你可以使用以下片段:
String plainText = new String(converted, StandardCharsets.UTF_8);
System.out.println(plainText);
Run Code Online (Sandbox Code Playgroud)
而不是你现在拥有的.
所以感谢@owlstead,我能够找出解决方案。是我犯了 Base64encoding 一个已经 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 "";
}
Run Code Online (Sandbox Code Playgroud)
对应的加密是这样的
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 "";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26599 次 |
| 最近记录: |