Java CipherOutputStream在接收消息时导致IllegalBlockSizeException
我正在编写使用AES的服务器/客户端系统。 以下方法(服务器端)工作正常:Java CipherOutputStream在接收消息时导致IllegalBlockSizeException,java,encryption,Java,Encryption,我正在编写使用AES的服务器/客户端系统。 以下方法(服务器端)工作正常: public static byte[] encode(byte type, byte subType, String string, Cipher cipher) throws NullPointerException, IOException { Objects.requireNonNull(string); Objects.requireNonNu
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;
}
但当我用下面的代码替换它时,我在客户端得到了非法的BlockSizeException
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) {};
}
}
}
第二种方法有什么问题?两种方法使用相同的密码。除编码方法外,服务器上没有任何更改。在从字节输出流提取字节之前,必须关闭CipherOutputStream。只有在close()方法中,密码对象才最终确定。而且,这样做可以大大简化异常处理。谢谢!已测试-它可以工作。如果您想使用更少的错误处理,请将
UTF_8.name()
替换为UTF_8
。