Générer une clé DES et la passer à travers le socket en Java


Quelqu'un pourrait-il m'aider à comprendre le problème dans mon programme très facile?

Lors de la sortie du message sur le serveur, je voudrais voir le même message qui a été envoyé sur le réseau, mais je n'en reçois pas.

Voici mon code pour le client:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.crypto.*;

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        String message = "The quick brown fox jumps over the lazy dog.";
        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        CipherOutputStream cipherOut = new CipherOutputStream(s.getOutputStream(), cipher);
        System.out.println(message.getBytes().length);
        cipherOut.write(message.getBytes());
    }
}

Et voici mon code pour le serveur:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        System.out.println(key.getClass().getName());
        in.close();

        // -Use the key to decrypt the incoming message from socket s.      
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        CipherInputStream cipherIn = new CipherInputStream(s.getInputStream(), cipher);
        byte[] stringInBytes = new byte[44];
        cipherIn.read(stringInBytes);
        String string = new String(stringInBytes);

        // -Print out the decrypt String to see if it matches the orignal message.
        System.out.println(string);
    }
}

Sortie Console côté serveur:

javax.crypto.spec.SecretKeySpec
}#ùÂ?°ô0íÿ| r|XÌ\?ñwŽ³{Í@nŠ?

Sortie Console côté client:

44

Voici mon nouveau code client:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        // -Connect to a server.
        String message = "The quick brown fox jumps over the lazy dog.";
        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = cipher.doFinal(message.getBytes());
        DataOutputStream dOut = new DataOutputStream(s.getOutputStream());
        dOut.writeInt(encVal.length); // write length of the message
        dOut.write(encVal);           // write the message
    }
}

Voici mon nouveau code pour le serveur:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        in.close();

        // -Use the key to decrypt the incoming message from socket s.    
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);

        DataInputStream dIn = new DataInputStream(s.getInputStream());
        int length = dIn.readInt();                    // read length of incoming message
        if(length>0) 
        {
            byte[] messageInBytes = new byte[length];
            dIn.readFully(messageInBytes, 0, messageInBytes.length); // read the message

            // -Print out the decrypt String to see if it matches the orignal message.
            System.out.println(new String(cipher.doFinal(messageInBytes)));
        }
    }
}

Voici une erreur que je reçois côté serveur:

Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.DataInputStream.readInt(Unknown Source)
    at encryption.CipherServer.main(CipherServer.java:26)

Et il n'y a pas d'erreurs côté client.

Author: ohidano, 2017-08-04

1 answers

Je pense qu'il y a une "course" entre votre client et votre serveur pour écrire et lire à partir de votre fichier de clé. Au moins, cela l'a fait pour moi quand j'ai exécuté votre code.

Essayez de mettre la génération de clé et l'écriture dans le fichier de clé avant de créer votre socket. De cette façon, lorsque votre client crée son socket, le serveur l'accepte et lorsqu'il accède au fichier, il obtient un fichier valide.

Cela fonctionne pour moi avec presque aucune différence par rapport à votre code en dehors de l'écriture sur le bit de fichier.

Le client:

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        String message = "The quick brown fox jumps over the lazy dog.";
        System.out.println("Message converted from Bytes = " + new String(message.getBytes()));
        System.out.println("Length = " + message.getBytes().length);

        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        CipherOutputStream cipherOut = new CipherOutputStream(s.getOutputStream(), cipher);
        cipherOut.write(message.getBytes());
        cipherOut.close();
        s.close();
    }
}

Et le Serveur:

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        in.close();

        // -Use the key to decrypt the incoming message from socket s.      
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        CipherInputStream cipherIn = new CipherInputStream(s.getInputStream(), cipher);

        byte[] array = new byte[44];
        cipherIn.read(array);
        cipherIn.close();
        s.close();

        String message = new String(array);
        System.out.println(message);
    }
}
 1
Author: Maaaatt, 2017-08-04 10:32:00