簡體   English   中英

DataOutputStream僅在關閉時發送

[英]DataOutputStream only sends on close

當我運行此代碼而不使用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可以正常工作!

加密代碼:

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密碼。 根據適用於JDK 8Java密碼體系結構標准算法名稱文檔 (經過重新格式化,並帶有鏈接的原始文檔 ):

AES

NIST在FIPS 197中指定的高級加密標准。 AES也被Joan Daemen和Vincent Rijmen稱為Rijndael算法,它是一種128位的分組密碼,支持128、192和256位的密鑰。

要僅使用一個有效密鑰大小來使用AES密碼,請使用AES_格式,其中可以為128、192或256。

哥倫比亞廣播公司

密碼塊鏈接模式,如FIPS PUB 81中所定義。

PKCS5填充

RSA實驗室,“ PKCS#5:基於密碼的加密標准”,版本1.5(1993年11月)中描述的填充方案。

因此,可能使用128位(16字節)的帶有填充的分組密碼。

密碼算法模式中注意這一點:

CFB,CFBx

密碼反饋模式,如FIPS PUB 81中所定義。

使用CFB和OFB等模式,分組密碼可以以小於密碼實際分組大小的單位加密數據。 當請求這種模式時,可以選擇將每次處理的位數附加到模式名稱中,以指定一次要處理的位數,如“ DES / CFB8 / NoPadding”和“ DES / OFB32 / PKCS5Padding”轉換所示。 如果未指定此數字,則使用提供程序特定的默認值。 (例如,SunJCE提供程序對DES使用默認的64位。) 因此,可以使用8位模式(例如CFB8或OFB8 )將塊密碼轉換為面向字節的流密碼

因此, "AES/CFB8/NoPadding"或類似文件應作為"AES/CFB8/NoPadding"流密碼工作。 但是,您可能仍然需要flush()流。 可能會對性能產生影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM