使用套接字传输加密文件并使用DES和MD5解密文件

时间:2017-08-04 09:43:30

标签: java sockets encryption cryptography des


我正在做一个应该保证数据传输的项目。我使用基于密码的加密与MD5和DES来加密文件。
加密文件的类:

public class FileEncryptor {    
    private static String filename;
    private static String password;
    private static FileInputStream inFile;
    private static FileOutputStream outFile;
    public static String tempFilename;
    public static File tempFile;

    public static File encryptFile(File f, String passkey) throws Exception {
        if(f.isDirectory()) {
            JOptionPane.showMessageDialog(null, "file object is a directory");
            return null;
        }
        filename = f.getPath();
        password = passkey;     
        //Need to create a temporary file which is filled with the encrypted data.
        tempFilename = filename + ".des";
        tempFile = new File(tempFilename);      
        inFile = new FileInputStream(f);
        outFile = new FileOutputStream(tempFile);       
        // Use PBEKeySpec to create a key based on a password.
        // The password is passed as a character array.
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory sKeyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey sKey = sKeyFac.generateSecret(keySpec);       
        byte[] salt = new byte[8];
        Random rnd = new Random();
        rnd.nextBytes(salt);
        int iterations = 100;       
         //Create the parameter spec for this salt and iteration count
        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);
        //Create the cipher and initiate it for encryption
        Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
        c.init(Cipher.ENCRYPT_MODE, sKey, parameterSpec);

        //Need to write the salt into the file. It is required for decryption
        outFile.write(salt);

        //Read the file and encrypt its bytes
        byte[] input = new byte[64];
        int bytesRead;
        while((bytesRead = inFile.read(input)) != -1) {
            byte[] output = c.update(input, 0, bytesRead);
            if(output != null) { outFile.write(output); }           
        }

        byte[] output = c.doFinal();
        if(output != null) { outFile.write(output); }

        //Closing the streams before exiting.
        inFile.close();
        outFile.flush();
        outFile.close();

        return tempFile;
    }

}

解密文件的类:

public class FileDecryptor {
 
    private static String filename;
    private static String password;
    private static FileInputStream inFile;
    private static FileOutputStream outFile;

    public static File decryptFile(File encryptedFile, String passkey) throws NoSuchAlgorithmException, 
                                                            InvalidKeySpecException, IOException, NoSuchPaddingException,
                                                            InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

        String encryptedfilename = encryptedFile.getPath();
        password = passkey;

        inFile = new FileInputStream(encryptedFile);
        StringBuffer sb = new StringBuffer(encryptedfilename);
        sb.reverse();
        sb.delete(0, 3);
        sb.reverse();           //removing the ".des" extension of the encrypted file
        filename = new String(sb) + ".dec";

        File decrypFile = new File(filename);
        outFile = new FileOutputStream(decrypFile);

        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory sKeyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey sKey = sKeyFac.generateSecret(keySpec);

        // Read in the previously stored salt and set the iteration count.
        byte[] salt = new byte[8];
        inFile.read(salt);
        int iterations = 100;

        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);

        //Create the cipher and initialize it for decryption.
        Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
        c.init(Cipher.DECRYPT_MODE, sKey, parameterSpec);

        byte[] input = new byte[64];
        int bytesRead;
        while((bytesRead = inFile.read(input)) != -1) {
            byte[] output = c.update(input, 0, bytesRead);
            if(output != null) {
                outFile.write(output);
            }
        }

        byte[] output = c.doFinal();
        System.out.println("Decrypted the data....");
        System.out.println("Wrting the data into file!!");
        if(output != null) {
            outFile.write(output);
        }
        System.out.println("Closing the streams");
        inFile.close();
        outFile.flush();
        outFile.close();

        return decrypFile;      
    }
}

发送逻辑:

public static void main(String[] args) {
       // TODO Auto-generated method stub
       Socket cs;
       OutputStream os;
       FileInputStream fis;
       byte[] b = new byte[6022386];
       File f = new File("D:\\abc.txt");
       File tempFile;

       try {
           tempFile = FileEncryptor.encryptFile(f, "impetus");
           fis = new FileInputStream(tempFile);
           ServerSocket ss = new ServerSocket(7007);
           System.out.println("Created and listening...");
           while(true) {
               System.out.println("Incoming connection!!!!!!!!");
               cs  = ss.accept();
               System.out.println("Client connected");
               os = cs.getOutputStream();
               fis.read(b);
               System.out.println("Sending the encrypted data");
               os.write(b);
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

接收逻辑:

public static void main(String[] args) {
       // TODO Auto-generated method stub
       File f = new File("D:\\P2PFolder\\ToDec.txt.des");
       FileOutputStream fos;
       InputStream is;
       Socket s;
       int bytesRead = 0;
       int current = 0;
       byte[] rb = new byte[6022386];
       try {
           fos = new FileOutputStream(f);
           System.out.println("Connecting.....");
            s = new Socket(InetAddress.getLocalHost(), 7007);
            System.out.println("Connected!!!");
            is = s.getInputStream();
            do {
                System.out.println("Reading encrypted data from socket");
                bytesRead = is.read(rb, current, (rb.length - current));
                System.out.println(new String(rb) + bytesRead);
                if(bytesRead > 0) {
                    current += bytesRead;
                }
            } while(bytesRead > -1);
           fos.write(rb);
           is.close();
           fos.flush();
           fos.close();
           System.out.println("Decrypting the file");
           FileDecryptor.decryptFile(f, "impetus");
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

没有抛出异常,但也没有传输数据。加密部分成功完成。但转移和解密没有发生。我检查了没有加密传输文件的代码,它正在工作。加密和解密类在单独使用时也可以正常工作,无需文件传输。有人可以指出我在哪里错了。如果代码太长但我必须提供我尝试的内容,我很抱歉。

1 个答案:

答案 0 :(得分:1)

  1. 您没有关闭服务器中的os,因此客户端副本循环永远不会终止。

  2. 修复后,您会发现文件太大了。

    fis.read(b);
    System.out.println("Sending the encrypted data");
    os.write(b);
    
  3. 问题是你的两个不同的复制过程都是错误的。在Java中复制流的规范方法如下:

    byte[] buffer = new byte[8192]; // or more
    int count;
    while ((count = in.read(buffer)) > 0)
    {
        out.write(buffer, 0, count);
    }
    

    两端使用此功能。您不需要文件大小的缓冲区,也不需要更大的缓冲区。