更新:我在代码中删除了另一个问题,以使问题更加精确。
我需要使用 AES / CBC / NoPadding 加密长度可变的字符串,但是我收到了IllegalBlockSizeException。 我必须使用NoPadding ,因为即使解密失败,输入也应该与输出具有相同的长度。 不应该确定它失败了。
在我使用 AES / CBC / PKCS5Padding 之前没有任何问题,但这不是一个选项。所以我的问题是:
如何添加自定义填充以获取16字节的倍数或可能导致IllegalBlockSizeException(DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH)?我还读到,密文窃取是一种方法。我很感激一个例子。
这是我目前的代码:
private static final String KEY_TRANSFORMATION_ALGORITHM_SYM = "AES/CBC/NoPadding";
@NonNull
static String encryptMessage(@NonNull String plainMessage,
@NonNull SharedPreferences storage,
@Nullable Key aesKey,
@NonNull String charset) {
if (aesKey == null) {
throw new RuntimeException("AES key is null", null);
}
try {
// Cipher can not be re-used on Android
Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION_ALGORITHM_SYM);
cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(getIV(storage, cipher, charset)));
byte[] charsetEncryptedData = cipher.doFinal(plainMessage.getBytes(charset));
return Base64.encodeToString(charsetEncryptedData, Base64.NO_WRAP);
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException | BadPaddingException | IllegalBlockSizeException | UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@NonNull
static String decryptMessage(@NonNull String encryptedMessage,
@NonNull SharedPreferences storage,
@Nullable Key aesKey,
@NonNull String charset) {
if (aesKey == null) {
throw new RuntimeException("AES key is null", null);
}
try {
//Cipher can not be re-used on Android
Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION_ALGORITHM_SYM);
cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(getIV(storage, cipher, charset)));
byte[] decryptedData = Base64.decode(encryptedMessage.getBytes(charset), Base64.NO_WRAP);
byte[] charsetEncryptedData = cipher.doFinal(decryptedData);
return new String(charsetEncryptedData, charset);
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
答案 0 :(得分:0)
我用以下代码解决了我的问题。我不得不添加一个带空格的自定义填充:
@NonNull
static String encryptMessage(@NonNull String plainMessage,
@NonNull SharedPreferences storage,
@Nullable Key aesKey,
@NonNull String charset) {
//...
// add spaces (custom padding) until the plainMessage.getBytes can be divided by 16 without rest --> this is the solution I was looking for
while (plainMessage.getBytes().length % 16 != 0) {
plainMessage += '\u0020';
}
//...
}
@NonNull
static String decryptMessage(@NonNull String encryptedMessage,
@NonNull SharedPreferences storage,
@Nullable Key aesKey,
@NonNull String charset) {
//...
// trim the String to get rid of the spaces
return new String(charsetEncryptedData, charset).trim();
//...
}