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

/**
 * <p>Example 3 exercises the KeyGenerator & Cipher
 *    classes.
 *    
 */
public class Example3
{
  public static void main(String args[])
  {
    try
    {
      System.out.println("Seeding random number generator ...");
      SecureRandom rand = new SecureRandom();
      rand.nextInt();
  
      // We want the DES cipher algorithm in CBC mode with PKCS#5 padding
      Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

      // We want DES keys with key length = 64 bits
      KeyGenerator kg = KeyGenerator.getInstance("DES");
      kg.init(64, rand);

      while (true)
      {
        // Generate the key
        System.out.println("\nGenerating key ...");
        SecretKey key = kg.generateKey();
  
        // Initial vector
        byte[] iv = new byte[8];
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
  
        // Initialize the cipher for encryption
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
  
        // The message to encrypt
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader in = new BufferedReader(isr);
        System.out.print("\nEnter message to encrypt: ");
        byte plainText[] = in.readLine().getBytes();
  
        // Encrypt the message
        byte[] cipherText = cipher.doFinal(plainText);
        debug("cipherText: ", cipherText);
  
        // Initialize the cipher for decryption
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        
        // Decrypt it
        plainText = cipher.doFinal(cipherText);
        System.out.println("Decrypted message: " + new String(plainText));
      }
    }
      catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  protected static void debug(String msg, byte bytes[])
  {
    System.out.print(msg);
    for (int i=0; i<bytes.length; i++)
    {
      System.out.print(java.lang.Integer.toHexString(bytes[i] & 0xff) + " ");
    }
    System.out.println(" ");
  }
}
