我正在做一个简单的项目,其中客户端使用JCE(DES)加密文件,然后使用套接字将其发送到服务器。服务器接收并解密它,直到服务器必须解密该文件为止,它可以正常工作,实际上应该返回解密的纯文本的CipherInputStream结果为null,但是我在函数中使用的FileInputStream可以,所以我不这样做真的不知道可能是什么问题。
客户:
import jdk.internal.util.xml.impl.Input;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Scanner;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
static private int porta = 81;
static private String hostname = "localhost";
public static void main(String[] args) {
OutputStream outputStream = null;
Socket socket = null;
boolean bIsConnected = false;
System.out.println("Inserisci il percorso del file che vuoi criptare");
Scanner in = new Scanner(System.in);
String path = in.nextLine(); //percorso da usare
System.out.println("Inserisci la chiave di criptazione");
String key = in.nextLine(); //Chiede la chiave di decriptazione (8 caratteri)
File plaintext = new File(path);
File encrypted = new File("Criptato.txt"); //salva il file nella cartella locale del progetto
try {
Encrypt(key, plaintext, encrypted);
System.out.println("Crittazione completata");
} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | IOException e) {
e.printStackTrace();
}
while (!bIsConnected) { //crittato il file aspetta che l'utente si colleghi al portale del server per mandare il file
try {
socket = new Socket(hostname, porta);
bIsConnected = true;
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
byte[] bytes = new byte[16 * 1024];
try {
InputStream inp = new FileInputStream(encrypted);//converte il file in uno stream
OutputStream outp = socket.getOutputStream();
int count;
while ((count = inp.read(bytes)) > 0) {
outp.write(bytes, 0, count); //scrive sulla socket del server il contenuto del file byte per byte
}
} //si collega all'output stream della socket
catch (IOException e) {
}
}
private static void write(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[64];
int numOfBytesRead;
while ((numOfBytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, numOfBytesRead);
}
out.close();
in.close();
}
public static void Encrypt(String key, File in, File out)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IOException {
FileInputStream fis = new FileInputStream(in);
FileOutputStream fos = new FileOutputStream(out);
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = skf.generateSecret(desKeySpec);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, SecureRandom.getInstance("SHA1PRNG"));
CipherInputStream cis = new CipherInputStream(fis, cipher);
write(cis, fos);
}
}
服务器:
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.io.*;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Scanner;
import java.net.*;
import java.nio.file.Files;
public class Main {
static private int portNumber = 81;
public static void main(String[] args) {
File criptato = new File("CriptatoServer.txt");
File decriptato = new File("Decrittato.txt");
System.out.println("Server running");
// Listening in entrata
ServerSocket socketServer;
try {
socketServer = new ServerSocket(portNumber);
} catch (IOException e) {
System.out.println("Impossibile ascoltare sulla porta.");
e.printStackTrace();
return;
}
while (true) {
Socket socket = null;
try {
socket = socketServer.accept();
} catch (IOException e) {
System.out.println("Impossibile accettare client.");
e.printStackTrace();
return;
}
System.out.println("Ricevuto client socket!");
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream(); //prende ciò che arriva dal client
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
out = new FileOutputStream(criptato); //scrive nel file criptato (sta copiando dal client)
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[16 * 1024];
int count;
try {
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
}catch(IOException e){System.out.println("AHIAIAI");}
System.out.println("Inserisci la chiave per decriptare il file e leggere il messaggio");
Scanner ins = new Scanner(System.in);
String key = ins.nextLine(); //chiave
try {
Decrypt(key, criptato, decriptato);
System.out.println("Decrittazione completata");
} catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | IOException e) {
e.printStackTrace();
}
}
}
private static void write(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[64];
int numOfBytesRead;
while ((numOfBytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, numOfBytesRead);
}
out.close();
in.close();
}
public static void Decrypt(String key, File in, File out)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IOException {
FileInputStream fis = new FileInputStream(in); //seems ok
FileOutputStream fos = new FileOutputStream(out);
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = skf.generateSecret(desKeySpec);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, SecureRandom.getInstance("SHA1PRNG"));
CipherInputStream cis = new CipherInputStream(fis, cipher); //returns null
write(cis, fos);
}
public static String getFileContent(
FileInputStream fis,
String encoding ) throws IOException
{
try( BufferedReader br =
new BufferedReader( new InputStreamReader(fis, encoding )))
{
StringBuilder sb = new StringBuilder();
String line;
while(( line = br.readLine()) != null ) {
sb.append( line );
sb.append( '\n' );
}
return sb.toString();
}
}
}
我知道这有点混乱,但我仍在努力。
答案 0 :(得分:0)
写完后,您忽略了关闭客户端套接字的输出端。因此,连接保持打开状态,服务器端仅在其读取循环中阻塞以等待更多输入。
您的异常处理非常复杂,实际上掩盖了代码的逻辑。在客户端,您可以执行以下操作:
InputStream inp = new FileInputStream(encrypted);//converte il file in uno stream
OutputStream outp = socket.getOutputStream();
int count;
while ((count = inp.read(bytes)) > 0) {
outp.write(bytes, 0, count); //scrive sulla socket del server il contenuto del file byte per byte
}
outp.close();
socket.close();