powerkor
powerkor

Reputation: 31

Three problems with Java cipher and socket stream

My three problems are as follows:

Using the asHex, I can prove the CipherServer.java gets the same bytes, but when decrypting the message, it doesn't decrypt correctly.

Am I missing something? I don't understand how the Client can decrypt it correctly but once passed through the stream, the Server cannot.

I've been looking around the Internet all day at examples and I can't figure it out. And before someone says something, I know DES isn't wise to use, however, this is just for a project, where DES is the requirement.

CIPHERCLIENT.java

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

import javax.crypto.*;

public class CipherClient
{public static void main(String[] args) throws Exception 
{
    try {
        //Starts socket
        String host = "localhost";
        int port = 8001;
        Socket s = new Socket(host, port);

        //Generate a DES key.
        KeyGenerator keygen = KeyGenerator.getInstance("DES");
        keygen.init(56, new SecureRandom());
        SecretKey key = keygen.generateKey();           

        //Store the key in a file
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        oos.writeObject(key);
        oos.close();

        //Start Cipher Instance and cipher the message
        //Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");            
        Cipher c = Cipher.getInstance("DES/ECB/NoPadding");
        c.init(Cipher.ENCRYPT_MODE,key);

        //Get string and encrypted version
        //String message = "The quick brown fox jumps over the lazy dog.";
        String message = "12345678";
        byte[] encryptedMsg = c.doFinal(message.getBytes("UTF-8"));

        System.out.println("Client - Message: " + message);
        System.out.println("Client - Encrypted: " + CipherServer.asHex(encryptedMsg));


        //TEST DECRYPT W/ KEY FILE W/O SERVER (WORKS!)
        //-------------------------------

        //Read key from file test
            ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
            SecretKey key2 = (SecretKey) file.readObject();
            System.out.println("Key Used: " + file.toString());
            file.close();

        //Decrypt Test
            c.init(Cipher.DECRYPT_MODE,key2);
            byte[] plainText = c.doFinal(encryptedMsg);
            System.out.println("Decrypted Message: " + new String(plainText));


        //Open stream to cipher server
        DataOutputStream os = new DataOutputStream(s.getOutputStream());
        os.writeInt(encryptedMsg.length);
        os.write(encryptedMsg);

        os.flush();
        os.close();

        //Close socket
        s.close();

    }catch (Exception e) {
        e.printStackTrace();
    }
}
 }

CIPHERSERVER.java

import java.io.*;
import java.net.*;
import java.security.NoSuchAlgorithmException;

import javax.crypto.*;


public class CipherServer
{
public static void main(String[] args) throws Exception 
{
    //Start socket server
    int port = 8001;
    ServerSocket s = new ServerSocket();
    s.setReuseAddress(true);
    s.bind(new InetSocketAddress(port));
    Socket client = s.accept();

    CipherServer server = new CipherServer();
    server.decryptMessage(client.getInputStream());

    s.close();
}


public void decryptMessage(InputStream inStream) throws IOException, NoSuchAlgorithmException
{
    try {

        //Create the Data input stream from the socket
        DataInputStream in = new DataInputStream(inStream);

        //Get the key
        ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        SecretKey key = (SecretKey) file.readObject();
        System.out.println("Key Used: " + file.toString());
        file.close();

        //Initiate the cipher
        //Cipher d = Cipher.getInstance("DES/ECB/PKCS5Padding");                        
        Cipher d = Cipher.getInstance("DES/ECB/NoPadding");
        d.init(Cipher.DECRYPT_MODE,key);

        int len = in.readInt();
        byte[] encryptedMsg = new byte[len];
        in.readFully(encryptedMsg);         

        System.out.println("Server - Msg Length: " + len);
        System.out.println("Server - Encrypted: " + asHex(encryptedMsg));


        //String demsg = new String(d.doFinal(encryptedMsg), "UTF-8");
        //System.out.println("Decrypted Message: " + demsg);
        // -Print out the decrypt String to see if it matches the orignal message.
        byte[] plainText = d.doFinal(encryptedMsg);
        System.out.println("Decrypted Message: " + new String(plainText, "UTF-8"));


    } catch (Exception e) {
        e.printStackTrace();
    }
}

//Function to make the bytes printable (hex format)
public static String asHex(byte buf[]) {
    StringBuilder strbuf = new StringBuilder(buf.length * 2);
    int i;
    for (i = 0; i < buf.length; i++) {
        if (((int) buf[i] & 0xff) < 0x10) {
            strbuf.append("0");
        }
        strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
    }
    return strbuf.toString();
}
 }

Upvotes: 4

Views: 1611

Answers (2)

Ebbe M. Pedersen
Ebbe M. Pedersen

Reputation: 7488

You create your socket to the server before you create the key file, and the server properly read the key from last run.

Try moving the Socket s = new Socket(host, port); to after you have closed the key file.

The events is as follows:

    Client                 Server
    -----------------      ------------------
    Connect to server
                           Accept connection
                           Read key file
                           (block on receive)
    Generate Key
    Write Key File
    Send message
                           Receive message
    etc.

Upvotes: 1

Maarten Bodewes
Maarten Bodewes

Reputation: 93948

Looking at the code I can only presume that the key is not correct. Maybe you are using a wrong folder or similar. BadPaddingException normally only occurs if the padding was incorrect, if the last block of the data has been corrupted or if you are using the wrong key. Maybe you could use a debugger or SecretKey.getEncoded() to check out if the keys together with your hexadecimal encoder.

Upvotes: 0

Related Questions