Java InputStream Crypting - PullRequest
       37

Java InputStream Crypting

0 голосов
/ 16 ноября 2018

Я делаю простой проект, в котором клиент шифрует файл с помощью JCE (DES) и отправляет его на сервер с помощью сокетов. Сервер получает и расшифровывает его. Он работает идеально до той части, где сервер должен расшифровать файл. На самом деле CipherInputStream, который должен возвращать результаты дешифрованного простого текста, равны нулю, но 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 голосов
/ 17 ноября 2018

Вы забыли закрыть выходную сторону клиентского сокета после того, как закончили писать в него. Таким образом, соединение остается открытым, и серверная сторона просто блокирует цикл чтения, ожидая больше ввода.

Ваша обработка исключений настолько сложна, что фактически затеняет логику вашего кода. На стороне клиента вы можете сделать что-то вроде:

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();
...