gpt4 book ai didi

java - DataOutputStream 仅在关闭时发送

转载 作者:行者123 更新时间:2023-12-02 02:12:23 24 4
gpt4 key购买 nike

当我在没有 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 下是底层的 Cipherstreams,没有它们也能工作!

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 来加密发送数据而不关闭?

提前致谢

最佳答案

来自

Cipher.getInstance("AES/CBC/PKCS5Padding")

您正在 CBC 模式下使用带有 PKCS5Padding 的 AES 密码。根据 Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8 (重新格式化,带有原始链接):

AES

Advanced Encryption Standard as specified by NIST in 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.

To use the AES cipher with only one valid key size, use the format AES_, where can be 128, 192, or 256.

CBC

Cipher Block Chaining Mode, as defined in FIPS PUB 81.

PKCS5Padding

The padding scheme described in RSA Laboratories, "PKCS #5: Password-Based Encryption Standard," version 1.5, November 1993.

因此,一个 block 密码,可能为 128 位(16 字节),带有填充。

请注意密码算法模式中的这一点:

CFB, CFBx

Cipher Feedback Mode, as defined in 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. 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. 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.

因此 "AES/CFB8/NoPadding" 或类似内容应该用作非阻塞流密码。但是,您可能仍然需要 flush() 流。并且可能会对性能产生影响。

关于java - DataOutputStream 仅在关闭时发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49803866/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com