//Secure Hash Algorithm 

package gov.va.med.authentication.kernel.sspi.authentication.manageable;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
//import org.myorg.SystemUnavailableException;
import sun.misc.BASE64Encoder;
import sun.misc.CharacterEncoder;

/**
 * 
 * @author VHIT Security and Other Common Services (S&OCS)
 * @version 1.1.0.002
 */
public final class BootUserPasswordEncryption
{
  private static BootUserPasswordEncryption instance;
  private BootUserPasswordEncryption()  {  }
  public synchronized String encrypt(String plaintext) throws Exception
  {
	MessageDigest md = null;
	/*Step 2:          Secure Hash Algorithm 
	 We are asking Java security API to obtain an instance of a message digest object 
	 using the algorithm supplied (in this case, SHA-1 message digest algorithm will be used. 
	 Both SHA and SHA-1 refer to the same thing, a revised SHA algorithm). 
	 Sun JDK includes JCA (Java Cryptography Architecture) which includes support for SHA algorithm. 
	 If your environment does not support SHA, NoSuchAlgorithmException will be thrown. 
	 **/
	try
	{
	  md = MessageDigest.getInstance("SHA"); //step 2
	}
	catch(NoSuchAlgorithmException e)
	{
	  throw new Exception(e.getMessage());
	}
	/* step 3           
	 Convert the plaintext password (eg, "jsmith") into a byte-representation using UTF-8 encoding format. 	
	 Apply this array to the message digest object created earlier. This array will be used as a 
	 source for the message digest object to operate on. 
	 */
	try
	{
	  md.update(plaintext.getBytes("UTF-8")); //step 3
	}
	catch(UnsupportedEncodingException e)
	{
	  throw new Exception(e.getMessage());
	}
	/* Step 4: 
	 Do the transformation: generate an array of bytes that represent the digested (encrypted) password value.
	 */ 
	byte raw[] = md.digest(); //step 4
	/* Step 5: 
	 Create a String representation of the byte array representing the digested password value. 
	 This is needed to be able to store the password in the database. At this point, the hash value 
	 of the plaintext "jsmith" is "5yfRRkrhJDbomacm2lsvEdg4GyY=". 
	 */
	String hash = (new BASE64Encoder()).encode(raw); //step 5
	
	return hash; 
  }
  /*  Step 1: The LoginController  servlet will interface with our PasswordService 
   * class using this static getInstance() method. Whenever it is invoked, a check will be 
   * made to see if an instance of this service class already exists. If so, it will be returned 
   * back to the caller. Otherwise, a new instance will be created. 
   */
  public static synchronized BootUserPasswordEncryption getInstance() //step 1
  {
	if(instance == null)
	{
	  return new BootUserPasswordEncryption();
	} 
	else    
	{
	  return instance;
	}
  }
}

