[英]DataOutputStream only sends on close
When I run this code without the close method the server cannot receive the message! 当我运行此代码而不使用close方法时,服务器将无法收到该消息!
client: 客户:
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();
server: 服务器:
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
Under the DataOutput/InputStream are Cipherstreams underlying without them it works! 在DataOutput / InputStream下, 没有它们的Cipherstreams可以正常工作!
EncryptIO code: 加密代码:
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;
}
How can I get it DataOutputStream to send the data with the encryption and without closing? 如何获得DataOutputStream以加密方式发送数据而不关闭?
Thanks in advance 提前致谢
From 从
Cipher.getInstance("AES/CBC/PKCS5Padding")
you're using an AES cipher in CBC mode with PKCS5Padding. 您在CBC模式下使用带有PKCS5Padding的AES密码。 Per the Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8 (reformatted, with links per the original):
根据适用于JDK 8的Java密码体系结构标准算法名称文档 (经过重新格式化,并带有链接的原始文档 ):
AES
AES
Advanced Encryption Standard as specified by NIST in FIPS 197 .
NIST在FIPS 197中指定的高级加密标准。 Also known as the Rijndael algorithm by Joan Daemen and Vincent Rijmen, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits.
AES也被Joan Daemen和Vincent Rijmen称为Rijndael算法,它是一种128位的分组密码,支持128、192和256位的密钥。
To use the AES cipher with only one valid key size, use the format AES_, where can be 128, 192, or 256.
要仅使用一个有效密钥大小来使用AES密码,请使用AES_格式,其中可以为128、192或256。
and 和
CBC
哥伦比亚广播公司
Cipher Block Chaining Mode, as defined in FIPS PUB 81 .
密码块链接模式,如FIPS PUB 81中所定义。
and 和
PKCS5Padding
PKCS5填充
The padding scheme described in RSA Laboratories, "PKCS #5: Password-Based Encryption Standard," version 1.5, November 1993 .
RSA实验室,“ PKCS#5:基于密码的加密标准”,版本1.5(1993年11月)中描述的填充方案。
So, a block cipher, likely at 128 bits (16 bytes), with padding. 因此,可能使用128位(16字节)的带有填充的分组密码。
Note this from Cipher Algorithm Modes : 从密码算法模式中注意这一点:
CFB, CFBx
CFB,CFBx
Cipher Feedback Mode, as defined in FIPS PUB 81 .
密码反馈模式,如FIPS PUB 81中所定义。
Using modes such as CFB and OFB, block ciphers can encrypt data in units smaller than the cipher's actual block size.
使用CFB和OFB等模式,分组密码可以以小于密码实际分组大小的单位加密数据。 When requesting such a mode, you may optionally specify the number of bits to be processed at a time by appending this number to the mode name as shown in the "DES/CFB8/NoPadding" and "DES/OFB32/PKCS5Padding" transformations.
当请求这种模式时,可以选择将每次处理的位数附加到模式名称中,以指定一次要处理的位数,如“ DES / CFB8 / NoPadding”和“ DES / OFB32 / PKCS5Padding”转换所示。 If no such number is specified, a provider-specific default is used.
如果未指定此数字,则使用提供程序特定的默认值。 (For example, the SunJCE provider uses a default of 64 bits for DES.) Thus, block ciphers can be turned into byte-oriented stream ciphers by using an 8-bit mode such as CFB8 or OFB8 .
(例如,SunJCE提供程序对DES使用默认的64位。) 因此,可以使用8位模式(例如CFB8或OFB8 )将块密码转换为面向字节的流密码 。
So "AES/CFB8/NoPadding"
or similar should work as a non-blocked stream cipher. 因此,
"AES/CFB8/NoPadding"
或类似文件应作为"AES/CFB8/NoPadding"
流密码工作。 You may still have to flush()
the stream, however. 但是,您可能仍然需要
flush()
流。 And there will likely be a performance impact. 可能会对性能产生影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.