简体   繁体   English

DataOutputStream仅在关闭时发送

[英]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 8Java密码体系结构标准算法名称文档 (经过重新格式化,并带有链接的原始文档 ):

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM