/**
  * Cifratura, decifratura e verifica di un messaggio con chiave simmetrica
  * NB: richiede la IAIK-JCE
  @author Enrico Denti
  @version 1.0, 2/3/99
*/

import java.security.Security;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.NoSuchProviderException;
import java.security.Key;

import javax.crypto.*;
import iaik.security.provider.*;

class EsempioGlobale {

  public static void main(String args[]){

	System.out.println("Aggiunta del nuovo provider IAIK");

	IAIK provider = new IAIK();
	Security.addProvider(provider);

	System.out.println("Aggiunta riuscita.");

	// -------- creazione generatore di chiavi------------------------

	System.out.println("Creazione del generatore di chiavi");

	KeyGenerator gen = null;
	try {
	  gen = KeyGenerator.getInstance("DES","IAIK");
	}
	catch (NoSuchAlgorithmException e1) {
	  System.out.println("Algoritmo non supportato in KeyGenerator");
	  System.exit(1);
	}
	catch (NoSuchProviderException e1) {
	  System.out.println("Provider non supportato in KeyGenerator");
	  System.exit(1);
	}
	System.out.println("Generatore di chiavi creato.");

	// -------- generazione chiave ------------------------------------

	System.out.println("Generazione della chiave segreta");

	gen.init(new SecureRandom());
	Key k = gen.generateKey();

	System.out.println("Chiave generata: ");
	for (int i=0; i<k.getEncoded().length; i++)
		System.out.print("" + k.getEncoded()[i] + "\t");
	System.out.println("");

	// -------- cifratura  ------------------------------------

	byte[] data = {10,20,30,40,50,60,70,80}, 
	       xxx = null, newdata = null;

	System.out.println("Messaggio in chiaro: ");
	for (int i=0; i<data.length; i++)
		System.out.print("" + data[i] + "\t");
	System.out.println("");

	// -------- creazione Cifratore -----------------

	System.out.println("Generazione del Cipher per l'algoritmo prescelto");

	Cipher des =  null;
	try {

	  des = Cipher.getInstance("DES","IAIK");

	  // ----- inizializzazione per cifratura --------

	  des.init(Cipher.ENCRYPT_MODE, k);
	  System.out.println("Cipher inizializzato per cifratura");

	  // -------- cifratura -------------------

	  xxx = des.doFinal(data);

	  System.out.println("Messaggio cifrato: ");
	  for (int i=0; i<xxx.length; i++)
		System.out.print("" + xxx[i] + "\t");
	  System.out.println("");

	  // ----- inizializzazione per decifratura --------

	  des.init(Cipher.DECRYPT_MODE, k);
	  System.out.println("Cipher inizializzato per decifratura");

	  // -------- decifratura ----------------

	  newdata = des.doFinal(xxx);

	  System.out.println("Messaggio decifrato: ");
	  for (int i=0; i<newdata.length; i++)
		System.out.print("" + newdata[i] + "\t");
	  System.out.println("");

	  // -------- verifica --------------------

	  boolean res = true;
	  if (data.length != newdata.length) res = false;
	  else
	  for (int j=0; j<data.length; j++)
		if (data[j] != newdata[j]) { res = false; break; }

	  System.out.println("Esito della verifica: " + res);

	}
	catch (NoSuchProviderException e2) {
	  System.out.println("Provider non supportato");
	  System.exit(2);
	}
	catch (NoSuchAlgorithmException e2) {
	  System.out.println("Algoritmo non supportato");
	  System.exit(2);
	}
	catch (NoSuchPaddingException e2) {
	  System.out.println("Tipo di padding non supportato");
	  System.exit(2);
	}
	catch (BadPaddingException e3) {
          System.out.println("Bad Padding");
          System.exit(3);
	}
	catch (InvalidKeyException e3) {
	  System.out.println("Chiave non valida");
	  System.exit(3);
	}
	catch (IllegalBlockSizeException ex) {
          System.out.println("Dimensione del blocco illegale");
          System.exit(3);
    	}

   }
}
