#java #encryption
#java #шифрование
Вопрос:
Я пишу серверную / клиентскую систему, которая использует AES. Следующий метод (на стороне сервера) работает нормально:
public static byte[] encode(byte type, byte subType, String string, Cipher cipher)
throws NullPointerException, IOException {
Objects.requireNonNull(string);
Objects.requireNonNull(cipher);
byte[] data = null;
try {
data = string.getBytes(StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e1) {};
ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
bytesOutput.write(type);
bytesOutput.write(subType);
bytesOutput.write(data);
byte[] plainBytes = bytesOutput.toByteArray();
byte[] bytes = null;
try {
bytes = cipher.doFinal(plainBytes);
} catch (Exception e) {
e.printStackTrace();
}
byte[] base64Bytes = Base64.getEncoder().encode(bytes);
return base64Bytes;
}
Но когда я заменил его следующим кодом, я получил исключение IllegalBlockSizeException на стороне клиента.
public static byte[] encode(byte type, byte subType, String string, Cipher cipher)
throws NullPointerException, EncodingException {
Objects.requireNonNull(string);
Objects.requireNonNull(cipher);
byte[] data = null;
try {
data = string.getBytes(StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e1) {};
CipherOutputStream cipherOutput = null;
try {
ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
OutputStream base64Output = Base64.getEncoder().wrap(bytesOutput);
cipherOutput = new CipherOutputStream(base64Output, cipher);
cipherOutput.write(type);
cipherOutput.write(subType);
cipherOutput.write(data);
cipherOutput.flush();
byte[] bytes = bytesOutput.toByteArray();
return bytes;
} catch (IllegalStateException | IOException e) {
throw new EncodingException(e);
} finally {
if (cipherOutput != null)
try {
cipherOutput.close();
} catch (IOException e) {};
}
}
}
Что не так со вторым методом? Оба метода используют один и тот же шифр. На сервере ничего не изменилось, за исключением метода encode.
Комментарии:
1. Вы должны закрыть CipherOutputStream, прежде чем извлекать байты из ByteOutputStream. Только в методе close() объект cipher завершается. Кроме того, поступая таким образом, вы существенно упростите обработку исключений.
2. Спасибо! Проверено — работает.
3. И если вы хотите использовать еще меньше обработки ошибок, замените
UTF_8.name()
на justUTF_8
.