Java InputStream加密

时间:2018-11-16 18:39:47

标签: java sockets encryption cryptography jce

我正在做一个简单的项目,其中客户端使用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();
        }
    }
}

我知道这有点混乱,但我仍在努力。

1 个答案:

答案 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();