[英]Close CipherOutputStream without DataOutputStream & Socket
[英]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 8的Java密碼體系結構標准算法名稱文檔 (經過重新格式化,並帶有鏈接的原始文檔 ):
AES
NIST在FIPS 197中指定的高級加密標准。 AES也被Joan Daemen和Vincent Rijmen稱為Rijndael算法,它是一種128位的分組密碼,支持128、192和256位的密鑰。
要僅使用一個有效密鑰大小來使用AES密碼,請使用AES_格式,其中可以為128、192或256。
和
哥倫比亞廣播公司
密碼塊鏈接模式,如FIPS PUB 81中所定義。
和
PKCS5填充
因此,可能使用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.