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

import cryptix.*;
//import cryptix.provider.*;
//import cryptix.provider.key.*;
import xjava.security.Cipher;
//import xjava.security.KeyGenerator;
//import xjava.security.PaddingScheme;



/**
 * 	SimpleExample.java
 */

public class CryptoExample {

  public static void doDES() throws Exception {
    String text = "Here's a DES example";

    // Create a TripleDES key
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
    keyGenerator.init(168); // need to initialize with the keysize
    Key key = keyGenerator.generateKey();


    // Create a cipher using that key to initialize it
    javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);


    // Print out the bytes of the plaintext
    byte[] plaintext = text.getBytes("UTF8");
    System.out.println("(DES) Plaintext to encode: " + new String(plaintext));
    for (int i = 0; i < plaintext.length; i++) {
      System.out.print(plaintext[i] + " ");
    }

    // Perform the actual encryption
    byte[] ciphertext = cipher.doFinal(plaintext);
    // Print out the ciphertext
    System.out.println("\n\n(DES) Ciphertext: "+ new String(ciphertext));
    for (int i = 0; i < ciphertext.length; i++) {
      System.out.print(ciphertext[i] + " ");
    }


    // Re-initialize the cipher to decrypt mode
    cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);

    // Perform the decryption
    byte[] decryptedText = cipher.doFinal(ciphertext);
    String output = new String(decryptedText, "UTF8");

    System.out.println("\n\n(DES) Decrypted text: " + output);
  }





  public static void doRSA() throws Exception {
    String text = "I'm doing RSA encryption";

    // Create an RSA key pair
    KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA", "Cryptix");
    keyGenerator.initialize(512); // need to initialize with the keysize
    KeyPair keys = keyGenerator.generateKeyPair();


    // Create a cipher using that key to initialize it
    Cipher cipher = Cipher.getInstance("RSA", "Cryptix");
    cipher.initEncrypt(keys.getPublic());


    // Print out the bytes of the plaintext
    byte[] plaintext = text.getBytes("UTF8");
    System.out.println("\n(RSA) Plaintext: " + new String(plaintext));
    for (int i = 0; i < plaintext.length; i++) {
      System.out.print(plaintext[i] + " ");
    }

    //Need to pad the cleartext before encryption (and depad after decryption)
    int blockSize = cipher.getPlaintextBlockSize();
    int padSize = blockSize - plaintext.length;

    byte[] plaintextPadded = new byte[blockSize];
    System.arraycopy(plaintext, 0, plaintextPadded, 0, plaintext.length);

    // Perform the actual encryption
    byte[] ciphertext = cipher.doFinal(plaintextPadded);
    // Print out the ciphertext
    System.out.println("\n\n(RSA) Ciphertext: "+ new String(ciphertext));
    for (int i = 0; i < ciphertext.length; i++) {
      System.out.print(ciphertext[i] + " ");
    }


    // Perform the decryption
    cipher.initDecrypt(keys.getPrivate());

    // Remove padding
    byte[] decryptedTextPadded = cipher.doFinal(ciphertext);
    byte[] decryptedText = new byte[blockSize - padSize];
    System.arraycopy(decryptedTextPadded, 0, decryptedText, 0, decryptedText.length);
    // Print result!!!!
    String output = new String(decryptedText, "UTF8");
    System.out.println("\n\n(RSA) Decrypted text: " + output);
  }



  //Main method
  public static void main(String[] args) throws Exception {
    //Include the Cryptix provider
    Provider cryptixProvider = new cryptix.provider.Cryptix();
    java.security.Security.addProvider(cryptixProvider);

    try {
      doDES();
      System.out.println("===================================================");
      doRSA();
    }
    catch(Exception e) {}

  }

}
