title: Three problems with Java cipher and socket stream
body: <p>My three problems are as follows:</p>
  
  <ul>
  <li><p>I can't figure out how to pad the bytes and have it work without the error: <code>javax.crypto.BadPaddingException: Given final block not properly padded</code></p></li>
  <li><p>If I switch it to NoPadding, I have to use a string thats a multiple of 8</p></li>
  <li><p>And lastly and most importantly, I can't get the Server to decrypt it correctly. I prove in the <em>CipherClient.java</em> that the decryption works before it gets sent over the socket.</p></li>
  </ul>
  
  <p>Using the asHex, I can prove the CipherServer.java gets the same bytes, but when decrypting the message, it doesn't decrypt correctly.</p>
  
  <p>Am I missing something? I don't understand how the Client can decrypt it correctly but once passed through the stream, the Server cannot.</p>
  
  <p>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.</p>
  
  <p><strong>CIPHERCLIENT.java</strong></p>
  
  <pre><code>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();
      }
  }
   }
  </code></pre>
  
  <p><strong>CIPHERSERVER.java</strong></p>
  
  <pre><code>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 &lt; buf.length; i++) {
          if (((int) buf[i] &amp; 0xff) &lt; 0x10) {
              strbuf.append("0");
          }
          strbuf.append(Long.toString((int) buf[i] &amp; 0xff, 16));
      }
      return strbuf.toString();
  }
   }
  </code></pre>