import java.io.*;
import java.security.*;
import java.util.*;
import java.sql.*;
class RSADSAGen
{
	public static void main(String args[])
	{
		if(args.length!=3){
			System.out.println("Usage: RSASignGen <name_of_file_to_sign>");
			System.exit(0);
		}
                
		try{
	        	java.util.Date date=Calendar.getInstance().getTime();

			/* ****************** BEGIN Generate a key pair *********************** */
			String algo="SHA1withDSA";
			if(algo.equals(args[2])){
				algo="DSA";
			}
			else{
				algo="RSA";
			}
			KeyPairGenerator keygen = KeyPairGenerator.getInstance(algo);
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG","SUN");

			keygen.initialize(Integer.parseInt(args[1]),random);

			KeyPair keypair = keygen.generateKeyPair();
			PrivateKey privatekey = keypair.getPrivate();
			PublicKey publickey = keypair.getPublic();
			/* ******************* END generating a key pair  ********************* */

			/* Create a Signature object and initialize it with private key */ 
			long start_signTime=Calendar.getInstance().getTimeInMillis();
			Signature rsa_dsa = Signature.getInstance(args[2]);
			rsa_dsa.initSign(privatekey);
                        
			/* ******************  Update and Sign the data  ********************** */
			FileInputStream fis = new FileInputStream("messagedigest"+args[0]);
                        BufferedInputStream bis = new BufferedInputStream(fis);
			byte buffer[] = new byte[1024];
			int length;
			while(bis.available() != 0){
				length = bis.read(buffer);
				rsa_dsa.update(buffer,0,length);
			}
			bis.close();

			/*
			 * Now, that all the data to be signed is read in, and hash generated ( using update method )
			 * generate a signature for it
			 */
			byte[] realsign = rsa_dsa.sign();
			long end_signTime=Calendar.getInstance().getTimeInMillis();

			/* ******* Inilize the Verification of signature with publickey ********* */
			long start_verifyTime=Calendar.getInstance().getTimeInMillis();
                        rsa_dsa.initVerify(publickey);

			/* ****************** UPDATE DATA and Verify Signature ****************** */
			fis = new FileInputStream("messagedigest"+args[0]);
                        bis = new BufferedInputStream(fis);
			while(bis.available() != 0){
				length = bis.read(buffer);
				rsa_dsa.update(buffer,0,length);
			}
			bis.close();
				
                        boolean status=rsa_dsa.verify(realsign);

			long end_verifyTime=Calendar.getInstance().getTimeInMillis();
			System.out.println(args[0]+"     "+args[1]+"        "+args[2]+"      "+(end_signTime-start_signTime)+"        "+(end_verifyTime-start_verifyTime)+"      "+status);

			/* ********** Save signature in a file ************ */
			algo="SHA1withDSA";
			if(algo.equals(args[2])){
	                        FileOutputStream sigfos = new FileOutputStream(args[0]+".dsa_sign");
        	                sigfos.write(realsign);
                	        sigfos.close();

	                        /* ********** Save Public key in a file ************ */
        	                FileOutputStream pubkeyfos = new FileOutputStream(args[0]+".dsa_sign_public_key");
                	        pubkeyfos.write(publickey.getEncoded());
			}
			else{
			        FileOutputStream sigfos = new FileOutputStream(args[0]+".rsa_sign");
                        	sigfos.write(realsign);
	                        sigfos.close();

        	                /* ********** Save Public key in a file ************ */
                	        FileOutputStream pubkeyfos = new FileOutputStream(args[0]+".rsa_sign_public_key");
                        	pubkeyfos.write(publickey.getEncoded());
	                        pubkeyfos.close();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
