当我在没有close方法的情况下运行此代码时,服务器无法接收消息!
客户:
Socket con = new Socket(InetAddress.getByName("localhost"), 12345);
InputStream is = con.getInputStream();
OutputStream os = con.getOutputStream();
byte[] key = new byte[]{5};
DataOutputStream dos = EncryptIO.getEncryptedOutputStream(key, os);
DataInputStream dis = EncryptIO.getEncryptedInputStream(key, is);
dos.writeUTF("Player 2");
dos.close(); //with this the server receives the message
String opUsername = dis.readUTF();服务器:
ServerSocket serverSocket = new ServerSocket(12345);
Socket con = serverSocket.accept();
InputStream is = con.getInputStream();
OutputStream os = con.getOutputStream();
byte[] key = new byte[]{5};
DataOutputStream dos = EncryptIO.getEncryptedOutputStream(key, os);
DataInputStream dis = EncryptIO.getEncryptedInputStream(key, is);
String opUsername = dis.readUTF();
System.out.println(opUsername);
dos.writeUTF("Player 1"); //this line isn't reached because DataInputStream waits for the data在DataOutput/InputStream下面是底层的密码流,而没有,它可以工作!
EncryptIO代码:
public static DataInputStream getEncryptedInputStream(byte[] key, InputStream is) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchPaddingException {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, EncryptIO.getAESKey(key), EncryptIO.getIV(key));
CipherInputStream cis = new CipherInputStream(is, cipher);
return new DataInputStream(cis);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(EncryptIO.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static DataOutputStream getEncryptedOutputStream(byte[] key, OutputStream os) throws InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, EncryptIO.getAESKey(key), EncryptIO.getIV(key));
CipherOutputStream cos = new CipherOutputStream(os, cipher);
return new DataOutputStream(cos);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(EncryptIO.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}如何才能让DataOutputStream发送加密和不关闭的数据?
提前感谢
发布于 2018-04-12 19:55:13
从…
Cipher.getInstance("AES/CBC/PKCS5Padding")您正在用PKCS5Padding在CBC模式下使用AES密码。根据JDK 8的Java密码体系结构标准算法名称文档 (重新格式化,并按原始链接):
AES NIST在FIPS 197中指定的高级加密标准。AES也被琼·戴门和文森特·里伊门称为Rijndael算法,是一种128位、192位和256位的支持密钥的128位分组密码。 若要使用只有一个有效密钥大小的AES密码,请使用格式AES_,其中可以是128、192或256。
和
CBC 密码块链接模式,如FIPS酒吧81中定义的。
和
PKCS5Padding RSA实验室,"PKCS #5:基于密码的加密标准“,版本1.5,1993年11月中描述的填充方案。
因此,一个块密码,可能在128位(16字节),与填充。
请注意,这来自密码算法模式
循环流化床,CFBx 密码反馈模式,如FIPS酒吧81中定义的。 使用CFB和OFB等模式,块密码器可以以比密码的实际块大小更小的单位加密数据。当请求这样的模式时,您可以选择一次指定要处理的位数,方法是将这个数字附加到模式名称中,如“DES/CFB8 8/NoPadding”和“DES/ of 32/PKCS5Padd”转换中所示。如果未指定此数字,则使用特定于提供程序的默认设置。(例如,SunJCE提供程序对DES使用64位的缺省值。)因此,通过使用8位模式(如CFB8或OFB8 ),块密码可以转换为面向字节的流密码。
因此,"AES/CFB8/NoPadding"或类似的应该作为一个非阻塞流密码工作。但是,您可能仍然必须对流进行flush()。而且很可能会对业绩产生影响。
https://stackoverflow.com/questions/49803866
复制相似问题