Java 关闭没有DataOutputStream的CipherOutputStream&;插座
我使用的是Java 关闭没有DataOutputStream的CipherOutputStream&;插座,java,sockets,encryption,dataoutputstream,Java,Sockets,Encryption,Dataoutputstream,我使用的是Cipher,其中连接在基础socket和dataoutputstream上。现在根据CipherOutputStream文档,为了释放加密机的最后一个块,我们需要调用close()。因此,将其与try with resource一起使用也会关闭我不想要的底层流,因为我需要它们来进行进一步的操作。 那么,是否有任何方法或实现可以帮助我在不使用dataoutputstream和socket的情况下关闭cipheroutputstream。?我听说过FilterOutputStream,
Cipher
,其中连接在基础socket
和dataoutputstream
上。现在根据CipherOutputStream
文档,为了释放加密机的最后一个块,我们需要调用close()
。因此,将其与try with resource一起使用也会关闭我不想要的底层流,因为我需要它们来进行进一步的操作。
那么,是否有任何方法或实现可以帮助我在不使用
dataoutputstream
和socket
的情况下关闭cipheroutputstream
。?我听说过FilterOutputStream,但我不知道如何使用它们。
我的代码:
public class ClientHandler implements Runnable {
Socket msock;
DataInputStream dis;
DataOutputStream dos;
String ip;
private miniClientHandler(Socket msock) {
this.msock = msock;
}
@Override
public void run() {
try {
dis = new DataInputStream(msock.getInputStream());
dos = new DataOutputStream(msock.getOutputStream());
ip = msock.getInetAddress().getHostAddress();
String msg = dis.readLine();
System.out.println(msg);
if (msg.equals("Download")) {
String file2dl = dis.readLine(); //2
File file = new File(sharedDirectory.toString() + "\\" + file2dl);
dos.writeLong(file.length()); //3+
//AES-128 bit key initialization.
byte[] keyvalue = "AES128BitPasswd".getBytes();
SecretKey key = new SecretKeySpec(keyvalue, "AES");
//Initialize the Cipher.
Cipher encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
encCipher.init(Cipher.ENCRYPT_MODE, key);
//Get the IV from cipher.
IvParameterSpec spec = null;
try {
spec = encCipher.getParameters().getParameterSpec(IvParameterSpec.class);
} catch (InvalidParameterSpecException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] iv = spec.getIV();
dos.write(iv, 0, iv.length); //4+
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
try (CipherOutputStream cos = new CipherOutputStream(dos, encCipher)) {
int read;
byte[] buffer = new byte[1024 * 1024];
while ((read = fis.read(buffer)) != -1) {
cos.write(buffer, 0, read); //5+ due to dos as underlying parameter of cos.
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
}
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
System.out.println(e.getMessage());
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024 * 1024];
byte[] cipherBlock = new byte[encCipher.getOutputSize(buffer.length)];
int cipherBytes;
int read;
while ((read = fis.read(buffer)) != -1) {
cipherBytes = encCipher.update(buffer, 0, read, cipherBlock);
dos.write(cipherBlock, 0, cipherBytes);
}
cipherBytes = encCipher.doFinal(cipherBlock, 0); //let out the last block out of the encryptor.
dos.write(cipherBlock, 0, cipherBytes);
} catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
现在,由于cos被包装在try with resource中,当while循环结束时,它关闭流和底层
dos
流,后者进一步包装了msock
,导致整个套接字关闭,剩下的代码没有用。
剩余代码:
public class ClientHandler implements Runnable {
Socket msock;
DataInputStream dis;
DataOutputStream dos;
String ip;
private miniClientHandler(Socket msock) {
this.msock = msock;
}
@Override
public void run() {
try {
dis = new DataInputStream(msock.getInputStream());
dos = new DataOutputStream(msock.getOutputStream());
ip = msock.getInetAddress().getHostAddress();
String msg = dis.readLine();
System.out.println(msg);
if (msg.equals("Download")) {
String file2dl = dis.readLine(); //2
File file = new File(sharedDirectory.toString() + "\\" + file2dl);
dos.writeLong(file.length()); //3+
//AES-128 bit key initialization.
byte[] keyvalue = "AES128BitPasswd".getBytes();
SecretKey key = new SecretKeySpec(keyvalue, "AES");
//Initialize the Cipher.
Cipher encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
encCipher.init(Cipher.ENCRYPT_MODE, key);
//Get the IV from cipher.
IvParameterSpec spec = null;
try {
spec = encCipher.getParameters().getParameterSpec(IvParameterSpec.class);
} catch (InvalidParameterSpecException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] iv = spec.getIV();
dos.write(iv, 0, iv.length); //4+
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
try (CipherOutputStream cos = new CipherOutputStream(dos, encCipher)) {
int read;
byte[] buffer = new byte[1024 * 1024];
while ((read = fis.read(buffer)) != -1) {
cos.write(buffer, 0, read); //5+ due to dos as underlying parameter of cos.
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
}
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
System.out.println(e.getMessage());
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024 * 1024];
byte[] cipherBlock = new byte[encCipher.getOutputSize(buffer.length)];
int cipherBytes;
int read;
while ((read = fis.read(buffer)) != -1) {
cipherBytes = encCipher.update(buffer, 0, read, cipherBlock);
dos.write(cipherBlock, 0, cipherBytes);
}
cipherBytes = encCipher.doFinal(cipherBlock, 0); //let out the last block out of the encryptor.
dos.write(cipherBlock, 0, cipherBytes);
} catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
在@EJP推荐的帮助下,我设法自己解决了问题,通过
update()
&doFinal()
代码:
public class ClientHandler implements Runnable {
Socket msock;
DataInputStream dis;
DataOutputStream dos;
String ip;
private miniClientHandler(Socket msock) {
this.msock = msock;
}
@Override
public void run() {
try {
dis = new DataInputStream(msock.getInputStream());
dos = new DataOutputStream(msock.getOutputStream());
ip = msock.getInetAddress().getHostAddress();
String msg = dis.readLine();
System.out.println(msg);
if (msg.equals("Download")) {
String file2dl = dis.readLine(); //2
File file = new File(sharedDirectory.toString() + "\\" + file2dl);
dos.writeLong(file.length()); //3+
//AES-128 bit key initialization.
byte[] keyvalue = "AES128BitPasswd".getBytes();
SecretKey key = new SecretKeySpec(keyvalue, "AES");
//Initialize the Cipher.
Cipher encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
encCipher.init(Cipher.ENCRYPT_MODE, key);
//Get the IV from cipher.
IvParameterSpec spec = null;
try {
spec = encCipher.getParameters().getParameterSpec(IvParameterSpec.class);
} catch (InvalidParameterSpecException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] iv = spec.getIV();
dos.write(iv, 0, iv.length); //4+
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
try (CipherOutputStream cos = new CipherOutputStream(dos, encCipher)) {
int read;
byte[] buffer = new byte[1024 * 1024];
while ((read = fis.read(buffer)) != -1) {
cos.write(buffer, 0, read); //5+ due to dos as underlying parameter of cos.
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
}
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
System.out.println(e.getMessage());
}
}
}
String message = dis.readLine();
System.out.println(message);
if (message.equals("Fetching Done")) {
System.out.println("Fetching Done!");
} else if (message.equals("Fetching Drop")) {
System.out.println("Fetching Denied!");
}
//Encryption Mechanism.
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024 * 1024];
byte[] cipherBlock = new byte[encCipher.getOutputSize(buffer.length)];
int cipherBytes;
int read;
while ((read = fis.read(buffer)) != -1) {
cipherBytes = encCipher.update(buffer, 0, read, cipherBlock);
dos.write(cipherBlock, 0, cipherBytes);
}
cipherBytes = encCipher.doFinal(cipherBlock, 0); //let out the last block out of the encryptor.
dos.write(cipherBlock, 0, cipherBytes);
} catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
}
您必须运行自己的
Cipher
对象,并在其上调用update()
和doFinal()
,而不是使用密码输出流,但您为什么不使用SSL?@EJP正在处理普通大学项目。而且,到目前为止,我还没有任何SSL方面的经验。反正我会调查的。请你提供一些代码片段的实现,这样我就可以把它标记为最终答案了。