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

/**
*  Class for verifying RSA signatures (e.g. created by RSASignGen). 
*  @param String name of file to verify
*  The signature should be stored in a file with same name and the extension .rsa_sign
*  The public key should be stored in a file with the same name and the extension .rsa_sign_public_key
*  The public key should be encoded using X.509
*/
public class RSASignVer
{
	public static void main(String args[])
	{
		if(args.length!=1){
			System.out.println("Usage: RSASignVer <name_of_file_to_verify (without extension)>");
			System.exit(0);
		}
		
		try {
			FileInputStream fisSign = new FileInputStream( args[0] + ".rsa_sign" );
			BufferedInputStream bisSign = new BufferedInputStream( fisSign );
			FileInputStream fisPublicKey = new FileInputStream( args[0] + ".rsa_sign_public_key" );
			BufferedInputStream bisPublicKey = new BufferedInputStream( fisPublicKey );
			FileInputStream fisMessage = new FileInputStream( args[0] );
			BufferedInputStream bisMessage = new BufferedInputStream( fisMessage );
	
			// read public key from file
			byte[] buffer3 = new byte[10000];
			int length = 400;
			int temp = 0;
			int offset = 0;
			while(bisPublicKey.available() != 0) { 
				temp = bisPublicKey.read(buffer3, offset, length);
				offset += temp;
			}
			long start = System.currentTimeMillis();
	
			X509EncodedKeySpec encodedKey = new X509EncodedKeySpec( buffer3 );
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic( encodedKey );
			Signature rsa = Signature.getInstance("SHA1withRSA");
			rsa.initVerify( publicKey );
			
			// read message from file and update signature
			byte buffer2[] = new byte[1024];
			int length2;
			while(bisMessage.available() != 0){
				length2 = bisMessage.read(buffer2);
				rsa.update(buffer2,0,length2);
			}

			// read signature from file
			byte buffer[] = new byte[10000];
			int length3 = 400;
			int offset3 = 0;
			while(bisSign.available() != 0){
				temp = bisSign.read(buffer, offset3, length3);
				offset3 += temp;
			}
	
			boolean verify = rsa.verify(buffer);
			long end= System.currentTimeMillis();
			System.out.println("Total elapsed time= "+ (end-start) );
			if (verify) {
				System.out.println("The signature is correct!");
			} else {
				System.out.println("The signature is wrong!");
			}

			bisSign.close();
			fisSign.close();
			bisPublicKey.close();
			fisPublicKey.close();
			bisMessage.close();
			fisMessage.close();
		} catch(Exception e) {
			e.printStackTrace();
		}

				
	}
}
