 
public class SecurityApplet extends Applet {
	//private String osName;
	private String browserName = new String();
	private JSObject jSObject = null;
	private BASE64Encoder bASE64Encoder = new BASE64Encoder();
	private BASE64Decoder bASE64Decoder = new BASE64Decoder();

	
	private String appletVersion = "41";	
			
	private final class CERT_DETAILS {
		private static final String NAME="Name" ;
		private static final String EMAIL="Email";
		private static final String CITY="City";
		private static final String STATE="State"; 
		private static final String COUNTRY="Country"; 
		private static final String EXPIRY_DATE="Expiry Date"; 
		private static final String DIGITAL_SIGN="Digital Signature"; 
		private static final String CN_NAME="CNName";
		private static final String ISSUER_ORG_NAME="Organization"; 
		private static final String ISSUER_ORG_UNIT="Organization Unit";
		private static final String ISSUER_COUNTRY="Issuer Country";
		private static final String ISSUER_CNAME="Issuer Name";
		private static final String ORG_NAME="Organoization Name";
		private static final String ORG_UNIT="Organization Unit";
		private static final String PUBLIC_KEY="Public Key";
		private static final String USAGE="Usage";
	}
	
	/*
	 * Signing Code
	 * jarsigner -keystore c:/my.keystore -storepass ozziepassword e:/securityApplet.jar ozzie
	 * jarsigner -verify e:/securityApplet.jar
	 */
	/**
	 * Generate Key Store
	keytool -genkey -alias ozzie -dname "cn=ozzie, ou=engr, o=YourCompanyName, c=US" -keypass ozziepassword -keystore C:\projectname\lib\security\.keystore -

	storepass ozziepassword 

	Sign JAr
	jarsigner -keystore \my.keystore -storepass ozziepassword /Users/kuntalshah/Desktop/V4Security.jar ozzie

	Verify JAR
	jarsigner -verify /Users/kuntalshah/Desktop/V4Security.jar
	
	Signing Command with full path
	"C:\Program Files (x86)\Java\jdk1.6.0_16\bin\jarsigner.exe" -keystore d:/my.keystore -storepass ozziepassword d:/securityApplet.jar ozzie
	 */
	
	@Override
	public void init() {
		printMessageToConsole("Applet Initialized Version : " + appletVersion);
		createOSPolicyFile();
		browserName = "Microsoft Internet Explorer";
	}
	
	private void createOSPolicyFile()  {
		File policyFile = new File(System.getProperty("user.home") + File.separator	+ ".java.policy");
		printMessageToConsole("Creating OS Policy File");
		try {
		printMessageToConsole("Policy File : " + policyFile.getAbsolutePath());
			if (policyFile.exists()) {
				policyFile.delete();
			}
		policyFile.createNewFile();
		FileOutputStream policyOutStream = new FileOutputStream(policyFile);
		String policyfileContent = "grant";
		policyfileContent = policyfileContent + "\n{";
		policyfileContent = policyfileContent + "permission java.security.AllPermission;";
		policyfileContent = policyfileContent + "\n};";
		policyOutStream.write(policyfileContent.getBytes());
		policyOutStream.flush();
		policyOutStream.close();
		} catch (Exception e) {
			printMessageToConsole("Exception on Creatign policy file : " + policyFile.getAbsolutePath());
			e.printStackTrace();
		}
	}

	// Configuration Methods
	/**
	 * Read the Os name from systemProperty
	 */
	public String getOsName() {
		try {
			String osName = System.getProperty("os.name");
			printMessageToConsole("Operating system name =>" + osName);
			return osName;
		} catch (Exception e) {
			printMessageToConsole("Error in Get OS Name.");
			e.printStackTrace();
			return null;
		}
	}

		// Initialize Key Stores
	private KeyStore initializeBrowserKeyStore() {
		KeyStore keyStore = null;
		printMessageToConsole("Initializing Key Store for " + browserName);
		try {
			keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
			keyStore.load(null, null);
		} catch (Exception e) {
			printMessageToConsole("Error in method: initializeBrowserKeyStore() -> initialize browser Key Store.");
			e.printStackTrace();
		}
		return keyStore;
	}
	
	public List<String> getCertificateAllDetails() throws NoSuchFieldException,
	SecurityException, IllegalArgumentException,
	IllegalAccessException, NoSuchMethodException,
			InvocationTargetException {
		printMessageToConsole("Get All Certificate Details");
		String certString = "";
		int count = 0;
		String pubKey = "";
		KeyStore browserKeyStore = null;
		String certDetails = "";
		browserKeyStore = initializeBrowserKeyStore();
		List<String> resultValues = new ArrayList<String>();
		String aliasnew = null;

		printMessageToConsole(browserName);
		if (browserKeyStore != null) {
			printMessageToConsole("INSIDE IE CERTIFICATE READING");
			Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
			spiField.setAccessible(true);
			KeyStoreSpi spi = (KeyStoreSpi) spiField.get(browserKeyStore);
			Field entriesField = spi.getClass().getSuperclass()
					.getDeclaredField("entries");
			entriesField.setAccessible(true);
			@SuppressWarnings("rawtypes")
			Collection entries = (Collection) entriesField.get(spi);
			resultValues.add("Total Certificates in Browser : "
					+ entries.size() + "<br><br><br>");
			printMessageToConsole("Total Certificates in Browser : "
					+ entries.size());
			for (Object entry : entries) {
				aliasnew = (String) invokeGetter(entry, "getAlias");
				PrivateKey privateKey = (PrivateKey) invokeGetter(entry,
						"getPrivateKey");
				X509Certificate[] certificateChain = (X509Certificate[]) invokeGetter(
						entry, "getCertificateChain");
				for (X509Certificate current : certificateChain) {
					certString = "";
					/*if (certDetails != null
							&& getkeyUsage(current.getKeyUsage()) != "") */
					{
						count++;
						pubKey = this.bASE64Encoder.encode(current
								.getPublicKey().getEncoded());
						certDetails = getX509CertificateDetails(current);
						Map<String, String> valueMap = new HashMap<String, String>();
						valueMap = getMetadata(certDetails);
						certString += "====================== Certificate Details for Certificate No : "
								+ count + "======================<br>";
						certString += "Alias : " + aliasnew + " <br>";
						certString += "Name : "
								+ valueMap.get(CERT_DETAILS.NAME) + " <br>";
						certString += "Email : "
								+ valueMap.get(CERT_DETAILS.EMAIL) + " <br>";
						certString += "City : "
								+ valueMap.get(CERT_DETAILS.CITY) + "<br>";
						certString += "State : "
								+ valueMap.get(CERT_DETAILS.STATE) + " <br>";
						certString += "Country : "
								+ valueMap.get(CERT_DETAILS.COUNTRY) + " <br>";
						certString += "Expiry Date : "
								+ valueMap.get(CERT_DETAILS.EXPIRY_DATE)
								+ "<br>";
						certString += "Issuer Organization : "
								+ valueMap.get(CERT_DETAILS.ISSUER_ORG_NAME)
								+ "<br>";
						certString += "Issuer Organization Unit : "
								+ valueMap.get(CERT_DETAILS.ISSUER_ORG_UNIT)
								+ "<br>";
						certString += "Key Usage : "
								+ getkeyUsage(current.getKeyUsage()) + "<br>";
						certString += "CNName : "
								+ valueMap.get(CERT_DETAILS.CN_NAME) + "<br>";
						// certString += "Public Key : " + pubKey + "\n";
						certString += "====================== "
								+ "<br><br><br>";
						printMessageToConsole(certString);
						resultValues.add(certString);
						break;
					}  
				}
			}
		} else {
			printMessageToConsole("Keystore is NULL");
		}
		return resultValues;
	}

	
	// Certificate Access Methods
	public String isCertificateInstalled(String pubKey) {
		String value = "false";
		PrivateKey privatekey = null;
		KeyStore keyStoreBrowser = null;
		printMessageToConsole("------------------------------Inside isCertificateInstalled method---------------------------------");
		try {
			keyStoreBrowser = initializeBrowserKeyStore();
			if (keyStoreBrowser!=null){
				printMessageToConsole("Browser Keys : " + keyStoreBrowser.size());
				privatekey = getPrivateKeyFromKeyStore(pubKey, keyStoreBrowser);
				if(privatekey != null) {
					value = "true";
				}
				else {
					printMessageToConsole("Private Key Not Found.");
				}
			}
			else {
				printMessageToConsole("Browser Keystore Null.");
			}
		} catch (Exception e) {
			printMessageToConsole("Exception in Certificate Installation Check.");
			e.printStackTrace();
		}
		printMessageToConsole("------------------------------End isCertificateInstalled method---------------------------------");
		return value;
	}
	
	private PrivateKey getPrivateKeyFromKeyStore(String pubkey,KeyStore browser) {
		PrivateKey privateKey = null;
		String pubKey1 = "";
		printMessageToConsole("Inside Get Private Key" );
		
		if (browser != null) {
			printMessageToConsole("Checking Browser Key Store keys for : " + browserName);
			try {
				Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
				spiField.setAccessible(true);
				KeyStoreSpi spi = (KeyStoreSpi) spiField.get(browser);
				Field entriesField = spi.getClass().getSuperclass().getDeclaredField("entries");
				entriesField.setAccessible(true);
				@SuppressWarnings("rawtypes")
				Collection entries = (Collection) entriesField.get(spi);
				for (Object entry : entries) {
					String alias = (String) invokeGetter(entry, "getAlias");
					X509Certificate[] certificateChain = (X509Certificate[]) invokeGetter(entry, "getCertificateChain");
					for (X509Certificate current : certificateChain) {
						pubKey1 = this.bASE64Encoder.encode(current.getPublicKey().getEncoded());
						if (pubkey.equals(pubKey1) && !pubkey.equals("")) {
							// Check for key usage and also put a null check 
							privateKey = (PrivateKey) invokeGetter(entry,"getPrivateKey");
							printMessageToConsole("Private Key is " + privateKey.toString());
							printMessageToConsole("Private Key Found from Browser");
							return privateKey;
						}
					}
				}
			} catch (Exception e) {
				printMessageToConsole("Exception while looping through browser certificates.");
				e.printStackTrace();
				return null;
			}
		
		}
		return privateKey;
	}
	

	private  String getX509CertificateDetails(X509Certificate cerificate) {
		String certDetails = "";
		printMessageToConsole("Inside Get Browser Certificate Details for Netscape.");
		try {
			if (cerificate.getSubjectAlternativeNames()!=null){
				String emailAddress[] = cerificate.getSubjectAlternativeNames().toString().split(",");
				if (!emailAddress.equals(null)) {
					certDetails = "E-Mail Address"
							+ "="
							+ emailAddress[1].substring(0,
									emailAddress[1].length() - 2) + ",";
				}
			}
			DateFormat dateFormat = new SimpleDateFormat(
					"HH:mm:ss a dd-MM-yyyy");
			certDetails += cerificate.getSubjectDN().getName() + "///"
					+ cerificate.getIssuerDN().getName();
			certDetails = certDetails + "///"
					+ dateFormat.format(cerificate.getNotBefore()) + "///"
					+ dateFormat.format(cerificate.getNotAfter());
			certDetails = certDetails + "///" + cerificate.getSigAlgName()
					+ "///" + cerificate.getSerialNumber();

			String[] keyUsagesData = { "digitalSignature", "nonRepudiation",
					"keyEncipherment", "dataEncipherment", "keyAgreement",
					"keyCertSign", "cRLSign", "encipherOnly", "decipherOnly" };
			boolean[] keyUsages = cerificate.getKeyUsage();

			if (keyUsages != null && keyUsages.length == 9) {
				String tmp = "";
				for (int i = 0; i < keyUsages.length; i++) {
					tmp = tmp + keyUsagesData[i] + "=" + keyUsages[i] + ",";
				}
				certDetails = certDetails + "///"
						+ tmp.substring(0, tmp.length() - 1);
			} else {
				certDetails = certDetails + "///" + "null";
			}
			printMessageToConsole("Certificate Details : " + certDetails);

		} catch (Exception e) {
			printMessageToConsole("Exception in Get Browser Certificate Details");
			e.printStackTrace();
			certDetails = e.getMessage();
		}

		return certDetails;
	}

	/**
	 * This method is used to get all Certificates details of IE.
	 * Certificate details will be separated by && and, two certificates will be separated by ||. 
	 * @return
	 * @author janki.panwala
	 */
	public String getAllCertificateDetail(){
		String certificatesString = "";
		try {
			printMessageToConsole("In method: getAllCertificateDetail()");
			KeyStore browserKeyStore = initializeBrowserKeyStore();
			if(browserKeyStore != null) {
				Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
				spiField.setAccessible(true);
				KeyStoreSpi spi = (KeyStoreSpi) spiField.get(browserKeyStore);
				Field entriesField = spi.getClass().getSuperclass().getDeclaredField("entries");
				entriesField.setAccessible(true);
				Collection entries = (Collection) entriesField.get(spi);
				for (Object entry : entries) {
					//PrivateKey privateKey = (PrivateKey) invokeGetter(certificate, "getPrivateKey");
					String aliasnew = (String) invokeGetter(entry, "getAlias");
					X509Certificate[] certificateChain = (X509Certificate[]) invokeGetter(entry, "getCertificateChain");
					for (X509Certificate certificate : certificateChain) {
						if(!getkeyUsage(certificate.getKeyUsage()).equals("")) {
							if(certificatesString != null && certificatesString.trim().length() > 0) {
								certificatesString += "||" + getCertificateDetailString(certificate);
							}
							else{
								certificatesString += getCertificateDetailString(certificate);
							}
						}
					}
				}
			}
			else{
				printMessageToConsole("Error in Method: getAllCertificateDetail()-> Browser key store is null");
			}
		} catch (Exception e) {
			printMessageToConsole("Error in Method: getAllCertificateDetail()");
		}
		return certificatesString;
	}
	
	private String getCertificateDetailString( X509Certificate certificate) {
		String certificateDetails = "";
		String digitalSign = "";
		try {
			String publicKey = this.bASE64Encoder.encode(certificate.getPublicKey().getEncoded());
			String certDetails = getX509CertificateDetails(certificate);
			int oCount = 0, cnCount = 0, ouCount = 0, cCount = 0;
			String[] certs = certDetails.split(",");
			if (certs.length > 0) {
				for (int i = 0; i < certs.length; i++) {
					String[] keyValue = certs[i].split("=");
					String certiField = "";
					if (keyValue.length == 2) {
						if (keyValue[0].trim().equals("CN") && cnCount == 0) {
							certDetails = CERT_DETAILS.NAME;
							cnCount++;
						} else if (keyValue[0].trim().equals("CN") && cnCount == 1) {
							certDetails = CERT_DETAILS.ISSUER_CNAME;
							cnCount++;
						} else if (keyValue[0].trim().equals("E-Mail Address")) {
							certDetails = CERT_DETAILS.EMAIL;
						} else if (keyValue[0].trim().equals("L")) {
							certDetails = CERT_DETAILS.CITY;
						} else if (keyValue[0].trim().equals("ST")) {
							certDetails = CERT_DETAILS.STATE;
						} else if (keyValue[0].trim().equals("C") && cCount == 0) {
							certDetails = CERT_DETAILS.COUNTRY;
							cCount++;
						} else if (keyValue[0].trim().equals("C") && cCount == 1) {
							certDetails = CERT_DETAILS.ISSUER_COUNTRY;
						} else if (keyValue[0].trim().equals("O") && oCount == 0) {
							certDetails = CERT_DETAILS.ORG_NAME;
							oCount++;
						} else if (keyValue[0].trim().equals("O") && oCount == 1) {
							certDetails = CERT_DETAILS.ISSUER_ORG_NAME;
							oCount++;
						} else if (keyValue[0].trim().equals("OU") && ouCount == 0) {
							certDetails = CERT_DETAILS.ORG_UNIT;
							ouCount++;
						} else if (keyValue[0].trim().equals("OU") && ouCount == 1) {
							certDetails = CERT_DETAILS.ISSUER_ORG_UNIT;
							ouCount++;
						} else if (keyValue[0].trim().equals("keyEncipherment")) {
							digitalSign = keyValue[1];
						}
						
						if(certDetails != "" && !keyValue[0].trim().equals("keyEncipherment")) {
							certDetails += "="+keyValue[1];
						}
						
					} else if (keyValue.length == 3) {
						if (keyValue[0].trim().equals("C")) {
							String[] subKeyValue = keyValue[1].split("///");
							if (subKeyValue.length > 2) {
								certDetails += CERT_DETAILS.EXPIRY_DATE +"="+subKeyValue[2];
							} else {
								certDetails += CERT_DETAILS.COUNTRY +"="+subKeyValue[0];
							}
						}
						if (keyValue[2].equals("true") || keyValue[2].equals("false")) {
							// valueMap.put(CERT_DETAILS.DIGITAL_SIGN, keyValue[2]);
						} else {
							certDetails = CERT_DETAILS.CN_NAME +"="+keyValue[2];
						}
					}
					
					if(certiField != "") {
						if(certs.length > 0 && i != certs.length - 1) {
							certificateDetails += certiField + "&&";
						}
						else {
							certificateDetails += certiField + "&&";
						}
					}
				}
			}
			
			/** Usage **/
			String usage = "";
			if (getkeyUsage(certificate.getKeyUsage()).equalsIgnoreCase("Non-Repudiation")) {
				usage = "Signing";
			} else if (getkeyUsage(certificate.getKeyUsage()).equalsIgnoreCase(	"KeyEncipherment")) {
				usage = "Encryption";
			}
			else {
				usage = digitalSign;
			}
			
			if(certificateDetails.endsWith("&&")) {
				certificateDetails += CERT_DETAILS.DIGITAL_SIGN + "="+usage;
			}
			else {
				certificateDetails += "&&"+CERT_DETAILS.DIGITAL_SIGN + "="+usage;
			}
			
			/** Set Public key **/
			if(certificateDetails.endsWith("&&")) {
				certificateDetails += CERT_DETAILS.PUBLIC_KEY + "="+publicKey;
			}
			else {
				certificateDetails += "&&"+CERT_DETAILS.PUBLIC_KEY + "="+publicKey;
			}
			
			printMessageToConsole("Certificate String: " + certificateDetails);
		} catch (Exception e) {
			printMessageToConsole("Error in Method: getCertificateDetailString()");
		}
		return certificateDetails;
	}
	
	/**
	 * @author Hardik Mishra
	 * @param alias
	 * @return
	 */
	public String getCertificateDetail(String type) {
		try {
			String alias = "";
			String pubKey = "";
			String certDetails = "";
			KeyStore browserKeyStore = null;
			printMessageToConsole("INSIDE METHOD OF getCertificateDetail");
			List<String> resultValues = new ArrayList<String>();

			X509Certificate cerificate = null;
			PrivateKey privatekey = null;
			browserKeyStore = initializeBrowserKeyStore();
			String aliasnew = null;

			{
				printMessageToConsole("Internet Explorer");
				if (browserKeyStore != null) {
					try {
						printMessageToConsole("INSIDE IE CERTIFICATE READING");
						Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
						spiField.setAccessible(true);
						KeyStoreSpi spi = (KeyStoreSpi) spiField.get(browserKeyStore);
						Field entriesField = spi.getClass().getSuperclass().getDeclaredField("entries");
						entriesField.setAccessible(true);
						@SuppressWarnings("rawtypes")
						Collection entries = (Collection) entriesField.get(spi);
						for (Object entry : entries) {
							aliasnew = (String) invokeGetter(entry, "getAlias");
							PrivateKey privateKey = (PrivateKey) invokeGetter(entry, "getPrivateKey");
							X509Certificate[] certificateChain = (X509Certificate[]) invokeGetter(entry, "getCertificateChain");
							for (X509Certificate current : certificateChain) {
								if(!getkeyUsage(current.getKeyUsage()).equals("")) {
									pubKey = this.bASE64Encoder.encode(current.getPublicKey().getEncoded());
									certDetails = getX509CertificateDetails(current);
									Map<String, String> valueMap = new HashMap<String, String>();
									if (certDetails != null) {
										valueMap = getMetadata(certDetails);
										if (type.equalsIgnoreCase("Name")) {
											resultValues.add(valueMap.get(CERT_DETAILS.NAME)+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("Email")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.EMAIL)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("City")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.CITY)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("State")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.STATE)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("Country")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.COUNTRY)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("Expiry Date")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.EXPIRY_DATE)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("Organization")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.ISSUER_ORG_NAME)
													+ "(" + aliasnew + ")");
										} else if (type
												.equalsIgnoreCase("Organization Unit")) {
											resultValues.add(valueMap
													.get(CERT_DETAILS.ISSUER_ORG_UNIT)
													+ "(" + aliasnew + ")");
										} else if (type.equalsIgnoreCase("Digital Signature")) {
											if (getkeyUsage(current.getKeyUsage()).equalsIgnoreCase("Non-Repudiation")) {
												resultValues.add("false");
											} else if (getkeyUsage(current.getKeyUsage()).equalsIgnoreCase(	"KeyEncipherment")) {
												resultValues.add("true");
											}
											else {
												resultValues.add(valueMap.get(CERT_DETAILS.DIGITAL_SIGN));
											}
										} else if (type.equalsIgnoreCase("PublicKey")) {

											resultValues.add((pubKey).toString());
										} else if (type.equalsIgnoreCase("CNName")) {
											resultValues.add(valueMap.get(CERT_DETAILS.CN_NAME)+ "(" + aliasnew + ")");
										} else {

										}
									} else {
										printMessageToConsole("CERTDETAILS IS NULL");
									}

									if (privatekey==null){
										printMessageToConsole("PRIVATE KEY IS NULL");
									}
									
									break;
								}
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
						printMessageToConsole("Error occure during IE certificate Reading");

					}
				} else {
					printMessageToConsole("Keystore is NULL");
				}
				String returnString = "";
				for (String value : resultValues) {
					returnString += value + "||";
				}
				return returnString;
			}
		} catch (Exception e) {
			e.printStackTrace();
			printMessageToConsole("Error occure during get CertificateeDetails");

		}
		return "";
	}
	// Get KeyUsage value from certificate
	private String getkeyUsage(boolean[] keyval) {
		boolean[] arykeyUsage = keyval;
		if(arykeyUsage != null) {
			for (int i = 0; i < 9; i++) {
				printMessageToConsole("value of KeyUsage::" + arykeyUsage[i]);
				if (arykeyUsage[i] && i == 2)
				{
					return "KeyEncipherment";
				} else if (arykeyUsage[i] && (i == 1 || i == 0)) {
					return "Non-Repudiation";
				}
			}
		}
		return "";
	}
	// Encryption, Decryption and Signing Methods

	public String Encrypt(String text, String pubkey) {
		printMessageToConsole("---------------------Inside Encrypt Method--------------------------------------");
		String encryptedText;
		PublicKey publicKey = null;
		Cipher cipher;
		try {
			publicKey = getPublicKeyFromString(pubkey);
			if (publicKey!=null) {
				if(text != null){
					byte[] plainText = text.getBytes();
					cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
					cipher.init(Cipher.ENCRYPT_MODE, publicKey);
					encryptedText = bASE64Encoder.encode(cipher.doFinal(plainText));
					/*cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
					cipher.init(Cipher.ENCRYPT_MODE, publicKey);
					byte[] encryptedData = Base64.encodeBase64(cipher.doFinal(text.getBytes()));
					encryptedText = new String(encryptedData);*/
				}
				else{
					encryptedText =  "Error@Encrypt: Null data received";
				}
			}
			else{
				encryptedText =  "Error@Encrypt: Public Key not found";
			}
		} 
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: Algorithm Not Found Exception."+ e.getMessage();
		} 
		catch (NoSuchPaddingException e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: No Such Padding Exception."+ e.getMessage();
		}
		catch (InvalidKeyException e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: Invalid Key Exception."+ e.getMessage();
		}
		catch (IllegalBlockSizeException e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: Illegal Block Size Exception."+ e.getMessage();
		} 
		catch (BadPaddingException e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: Bad Padding Exception.."+ e.getMessage();
		}
		catch (Exception e) {
			e.printStackTrace();
			encryptedText =  "Error@Encrypt: "+ e.getMessage();
		}
		printMessageToConsole("-------------------------------End Encrypt Method--------------------------------------");
		return encryptedText;

	}
	public String Decrypt(String text, String pubkey) {
		printMessageToConsole("--------------------------------Inside Decrypt Method-----------------------------------");
		PrivateKey privatekey = null;
		KeyStore keyStoreBrowser = null;
		String decryptedString;
		Cipher cipher = null;
		byte[] encryptText;
		try {
			keyStoreBrowser = initializeBrowserKeyStore();
			if(keyStoreBrowser != null) {
				privatekey = getPrivateKeyFromKeyStore(pubkey, keyStoreBrowser);
				if(privatekey != null) {
					if(text != null){
						encryptText = this.bASE64Decoder.decodeBuffer(text);
						cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
						cipher.init(Cipher.DECRYPT_MODE, privatekey);
						decryptedString = new String(cipher.doFinal(encryptText));
					/*	encryptText =  Base64.decodeBase64(text.getBytes());
						cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
						cipher.init(Cipher.DECRYPT_MODE, privatekey);
						decryptedString = new String(cipher.doFinal(encryptText));*/
					}
					else{
						decryptedString =  "Error@Decrypt: Null data received to decrypt.";
					}
				}
				else{
					printMessageToConsole("Private is null");
					decryptedString =  "Error@Decrypt: Private Key Not Found.";
				}
			}
			else{
				printMessageToConsole("KeyStore  not found");
				decryptedString =  "Error@Decrypt: KeyStore is null.";
			}
		}
		/*catch (IOException e) {
			e.printStackTrace();
			decryptedString =  "Error@Decrypt: IO Exception"+ e.getMessage();
		}*/
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt: Algorithm Not Found Exception."+ e.getMessage();
		} 
		catch (NoSuchPaddingException e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt: No Such Padding Exception."+ e.getMessage();
		}
		catch (InvalidKeyException e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt: Invalid Key Exception."+ e.getMessage();
		}
		catch (IllegalBlockSizeException e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt: Illegal Block Size Exception."+ e.getMessage();
		} 
		catch (BadPaddingException e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt: Bad Padding Exception.."+ e.getMessage();
		}
		catch (Exception e) {
			e.printStackTrace();
			decryptedString = "Error@Decrypt:"+ e.getMessage();
		}
		printMessageToConsole("--------------------------------End Decrypt Method-----------------------------------");
		return decryptedString;
	}
	public String SignData(String data, String pubkey) {
		printMessageToConsole("--------------------------------Inside Sign Method-----------------------------------");
		PrivateKey privatekey = null;
		KeyStore keyStoreBrowser = null;
		Signature signer;
		String signedData;
		try {
			keyStoreBrowser = initializeBrowserKeyStore();
			if(keyStoreBrowser != null) {
				privatekey = getPrivateKeyFromKeyStore(pubkey, keyStoreBrowser);
				if(privatekey != null) {
					if(data != null) {
						signer = Signature.getInstance("SHA1withRSA");
						signer.initSign(privatekey);
						signer.update(data.getBytes());
						signedData = new String(signer.sign());
					}
					else{
						signedData = "Error@Sign: Null data received";
					}
				}
				else{
					signedData = "Error@Sign: Private not found";
				}
			}
			else{
				signedData = "Error@Sign: KeyStore is null";
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			signedData = "Error@Sign: No Such Algorith Exception."+ e.getMessage();
		}
		catch (InvalidKeyException e) {
			e.printStackTrace();
			signedData = "Error@Sign: Invalid Key Exception."+ e.getMessage();
		}
		catch (SignatureException e) {
			e.printStackTrace();
			signedData = "Error@Sign: Signature Exception."+ e.getMessage();
		}
		catch(Exception e) {
			e.printStackTrace();
			signedData = "Error@Sign: "+ e.getMessage();
		}
		printMessageToConsole("--------------------------------End Sign Method-----------------------------------");
		return signedData;
	}
	/**
	 * Dhruti verifyData with publickey,Plaintext and SignData
	 */
	public String verifyData(String data, String publicKey) {

		byte[] digitalSignature = (SignData(data, publicKey)).getBytes();

		boolean result = true;
		Signature signer = null;
		try {
			signer = Signature.getInstance("SHA1withRSA");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return "Error@Verify: No Such Algorith Exception."+ e.getMessage();
		}
		PublicKey pubkey = getPublicKeyFromString(publicKey);
		if (publicKey==null)
			return "Error@Verify: Publick Key Null.";
		try {
			signer.initVerify(pubkey);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
			return "Error@Verify: Invalid Key Exception."+ e.getMessage();
		}

		try {
			signer.update(data.getBytes());
		} catch (SignatureException e) {
			e.printStackTrace();
			return "Error@Verify: Signature Exception."+ e.getMessage();
		}

		try {
			result = signer.verify(digitalSignature);
		} catch (SignatureException e) {
			e.printStackTrace();
			return "Error@Verify: Signature Exception."+ e.getMessage();

		}

		if (result == true) {
			return "TRUE";
		} else {
			return "FALSE";
		}
	}
	public static PublicKey getPublicKeyFromString(String key) {
		BASE64Decoder base64Decoder = new BASE64Decoder();
		PublicKey publicKey = null;
		try {
			publicKey = new RSAPublicKeyImpl(base64Decoder.decodeBuffer(key));
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return publicKey;
	}
	private Map<String, String> getMetadata(String certDetail) {
		// /CN=Test Organization Signing Certificate, ST=Test State,
		// OID.2.5.4.17=500050, OU=Test Department, O=Test Company Organization,
		// C=IN
		// /CN=Test TCS Sub-CA for TCS 2011, OU=Sub-CA, O=Tata Consultancy
		// Services Ltd., C=IN
		
		
		//Output
//		E-Mail Address= kuntal.shah@digi-corp.com,
//		CN=KUNTAL NITINBHAI SHAH, ST=GUJARAT, OID.2.5.4.17=380015, OU=DIRECTOR, 
//		O=DIGICORP INFORMATION SYSTEMS PVT LTD, C=IN
		///CN=SafeScrypt sub-CA for RCAI Class 3 2012, OU=Sub-CA, O=Sify Technologies Limited, C=IN
		///17:30:46 PM 20-02-2012
		///17:30:46 PM 20-02-2014
		///SHA256withRSA
		///94715422213
		///digitalSignature=true,nonRepudiation=true,keyEncipherment=false,dataEncipherment=false,keyAgreement=false,keyCertSign=false,cRLSign=false,encipherOnly=false,decipherOnly=false
		int oCount = 0, cnCount = 0, ouCount = 0, cCount = 0;
		printMessageToConsole(" Create Value Map For : " + certDetail);
		Map<String, String> valueMap = new HashMap<String, String>();
		String[] certs = certDetail.split(",");
		if (certs.length > 0) {
			for (int i = 0; i < certs.length; i++) {
				String[] keyValue = certs[i].split("=");
				if (keyValue.length == 2) {
					if (keyValue[0].trim().equals("CN") && cnCount == 0) {
						valueMap.put(CERT_DETAILS.NAME, keyValue[1]);
						cnCount++;
					} else if (keyValue[0].trim().equals("CN") && cnCount == 1) {
						valueMap.put(CERT_DETAILS.ISSUER_CNAME, keyValue[1]);
						cnCount++;
					} else if (keyValue[0].trim().equals("E-Mail Address")) {
						valueMap.put(CERT_DETAILS.EMAIL, keyValue[1]);
					} else if (keyValue[0].trim().equals("L")) {
						valueMap.put(CERT_DETAILS.CITY, keyValue[1]);
					} else if (keyValue[0].trim().equals("ST")) {
						valueMap.put(CERT_DETAILS.STATE, keyValue[1]);
					} else if (keyValue[0].trim().equals("C") && cCount == 0) {
						valueMap.put(CERT_DETAILS.COUNTRY, keyValue[1]);
						cCount++;
					} else if (keyValue[0].trim().equals("C") && cCount == 1) {
						valueMap.put(CERT_DETAILS.ISSUER_COUNTRY, keyValue[1]);
					} else if (keyValue[0].trim().equals("O") && oCount == 0) {
						valueMap.put(CERT_DETAILS.ORG_NAME, keyValue[1]);
						oCount++;
					} else if (keyValue[0].trim().equals("O") && oCount == 1) {
						valueMap.put(CERT_DETAILS.ISSUER_ORG_NAME, keyValue[1]);
						oCount++;
					} else if (keyValue[0].trim().equals("OU") && ouCount == 0) {
						valueMap.put(CERT_DETAILS.ORG_UNIT, keyValue[1]);
						ouCount++;
					} else if (keyValue[0].trim().equals("OU") && ouCount == 1) {
						valueMap.put(CERT_DETAILS.ISSUER_ORG_UNIT, keyValue[1]);
						ouCount++;
					} else if (keyValue[0].trim().equals("keyEncipherment")) {
						valueMap.put(CERT_DETAILS.DIGITAL_SIGN, keyValue[1]);
					}

				} else if (keyValue.length == 3) {
					if (keyValue[0].trim().equals("C")) {
						String[] subKeyValue = keyValue[1].split("///");
						if (subKeyValue.length > 2) {
							valueMap.put(CERT_DETAILS.EXPIRY_DATE,
									subKeyValue[2]);
						} else {
							valueMap.put(CERT_DETAILS.COUNTRY, subKeyValue[0]);
						}
					}
					if (keyValue[2].equals("true")
							|| keyValue[2].equals("false")) {
						// valueMap.put(CERT_DETAILS.DIGITAL_SIGN, keyValue[2]);
					} else {
						valueMap.put(CERT_DETAILS.CN_NAME, keyValue[2]);
					}
				}
			}
		}
		return valueMap;
	}
	public static String symmetricEncrypt(String text, String secretKey){
		System.out.println("--------------------------------Inside symmetric encrypt Method-----------------------------------");
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] raw;
		String encryptedString;
		SecretKeySpec skeySpec ;
		Cipher cipher;
		BASE64Encoder bASE64Encoder = new BASE64Encoder();
		try {
			if(text != null) {
			/*	 raw = Base64.decodeBase64(secretKey.getBytes());
	             skeySpec = new SecretKeySpec(raw, "AES");
	             cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
	             cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
	             byte[] encryptedData = Base64.encodeBase64(cipher.doFinal(text.getBytes()));
	             encryptedString = new String(encryptedData);
			*/	
				byte[] encryptText = text.getBytes();
				raw = decoder.decodeBuffer(secretKey);
				skeySpec = new SecretKeySpec(raw, "AES");
				cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
				cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
				encryptedString = bASE64Encoder.encode(cipher.doFinal(encryptText));
			}
			else{
				encryptedString = "Error@SymmetricEncrypt: Null data Received";
			}
		} 
		/*catch (IOException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: IO Exception " + e.getMessage();
		}*/
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: No Such Algorithm Exception " + e.getMessage();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: No Such Padding Exception " + e.getMessage();
		}
		catch (InvalidKeyException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: Invalid Key Exception " + e.getMessage();
		}
		catch (IllegalBlockSizeException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: IO Exception " + e.getMessage();
		} 
		catch (BadPaddingException e) {
			e.printStackTrace();
			encryptedString = "Error@SymmetricEncrypt: IO Exception " + e.getMessage();
		}
		catch (Exception e) {
			System.out.println(e.getCause().toString());
			encryptedString = "Error@SymmetricEncrypt: " + e.getMessage();
		}
		System.out.println("--------------------------------End symmetric encrypt Method-----------------------------------");
		return encryptedString;
	}
	public static String symmetricDecrypt(String text, String secretKey){
		System.out.println("--------------------------------Inside symmetric decrypt Method-----------------------------------");
		BASE64Decoder decoder = new BASE64Decoder();
		BASE64Decoder base64Decoder = new BASE64Decoder();
		Cipher cipher;
		String decryptedString;
		byte[] encryptText;
		byte[] raw;
		SecretKeySpec skeySpec;
		try {
			if(text != null) {
				/*raw = Base64.decodeBase64(secretKey.getBytes());
		        skeySpec = new SecretKeySpec(raw, "AES");
		        encryptText = Base64.decodeBase64(text.getBytes());
		        cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		        decryptedString = new String(cipher.doFinal(encryptText));*/
				raw = decoder.decodeBuffer(secretKey);
				skeySpec = new SecretKeySpec(raw, "AES");
				encryptText = base64Decoder.decodeBuffer(text);
				cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
				cipher.init(Cipher.DECRYPT_MODE, skeySpec);
				decryptedString = new String(cipher.doFinal(encryptText));
			}
			else {
				decryptedString =  "Error@SymmetricDecrypt: Null data received to decrypy.";
			}
		} 
		/*catch (IOException e) {
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: IO Exception " + e.getMessage();
		}*/
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: No Such Algorithm Exception " + e.getMessage();
		} 
		catch (NoSuchPaddingException e) {
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: No Such Padding Exception " + e.getMessage();
		}
		catch (InvalidKeyException e) {
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: Invalid Key Exception " + e.getMessage();
		}
		catch (IllegalBlockSizeException e) {
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: Illegal Block Size Exception " + e.getMessage();
		} 
		catch (BadPaddingException e) {	
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt: Bad Padding Exception " + e.getMessage();
		}
		catch(Exception e){
			e.printStackTrace();
			decryptedString =  "Error@SymmetricDecrypt:" + e.getMessage();
		}
		return decryptedString;
	}
	public static String getSecretKey() {
		KeyGenerator kgen;
		String strSecretkey;
		try {
			kgen = KeyGenerator.getInstance("AES");
			kgen.init(128);
			SecretKey secretkey = kgen.generateKey();
			BASE64Encoder encode = new BASE64Encoder();
			strSecretkey = encode.encode(secretkey.getEncoded());
		} 
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			strSecretkey = "Error@SecretKeyGeneration: No Such Algorith Exception. " + e.getMessage();
		}
		catch (Exception e) {
			e.printStackTrace();
			strSecretkey = "Error@SecretKeyGeneration: " + e.getMessage();
		}
		return strSecretkey;
	}
	// Common /\- Misc Methods
	public void printMessageToConsole(String message) {
		System.out.println(message);
	}
	private static Object invokeGetter(Object instance, String methodName)
			throws NoSuchMethodException, IllegalAccessException,
			InvocationTargetException {
		Method getAlias = instance.getClass().getDeclaredMethod(methodName);
		getAlias.setAccessible(true);
		return getAlias.invoke(instance);
	}
		public String getJavaVerify() {
			String result="";
			Object object5 = jSObject.call("getJavaVerify", null);

			if (object5 != null && object5 instanceof String) {
				result = (String) object5;
				printMessageToConsole("GOT Java Verify============" + result);
				if (result == "true" || result.equalsIgnoreCase("true")) {
					return "true";
				} else {
					return "false";
				}

			} else {
				return "false";
			}
		}
		public static String generateKeyPair() {
			KeyPairGenerator keyGen;
			//String[] keys = new String[(int) (2)];
			String strKeys = "";
			try {
				keyGen = KeyPairGenerator.getInstance("RSA");
				keyGen.initialize(2048);
				java.security.KeyPair pair = keyGen.generateKeyPair();
				PrivateKey privateKey = pair.getPrivate();
				PublicKey publicKey = pair.getPublic();
				byte[] publicEncoded = publicKey.getEncoded();
				byte[] privateEncoded = privateKey.getEncoded();
				BASE64Encoder base64Encoder = new BASE64Encoder();
				strKeys = base64Encoder.encode(publicEncoded);
				//keys[0] = strKey;
				strKeys +=","+ base64Encoder.encode(privateEncoded);
				//keys[1] = strKey;
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				strKeys = "Error@GenerateKeys: No algorithm found." + e.getMessage();
				//keys[0] = "Error@GenerateKeys: No algorithm found." + e.getMessage();
			} catch (Exception e) {
				e.printStackTrace();
				strKeys = "Error@GenerateKeys: Problem in generating keys." + e.getMessage();
				//keys[0] = "Error@GenerateKeys: Problem in generating keys." + e.getMessage();
			}
			return strKeys;
		}
	public static String publicEncrypt(String text, String pubKey){
			String encryptedText = null;
			try {
				PublicKey publicKey = getPublicKeyFromString(pubKey);
				BASE64Encoder bASE64Encoder = new BASE64Encoder();
				byte[] plainText = text.getBytes();
				Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(Cipher.ENCRYPT_MODE, publicKey);
				cipher.update(plainText);
				encryptedText = bASE64Encoder.encode(cipher.doFinal());
			} catch (Exception e) {
				e.printStackTrace();
				encryptedText = "Error@PublicEncrypt" + e.getMessage();
			}
			return encryptedText;
		}
		public static String privateDecrypt(String text, String priKey){
			String decryptedString = null;
			try {
				PrivateKey privateKey = getPrivateKeyFromString(priKey);
				BASE64Decoder base64Decoder = new BASE64Decoder();
				byte[] encryptText = base64Decoder.decodeBuffer(text);
				Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(Cipher.DECRYPT_MODE, privateKey);
				decryptedString = new String(cipher.doFinal(encryptText));
			} catch (Exception e) {
				e.printStackTrace();
				decryptedString = "Error@PrivateDecrypt." + e.getMessage();
			}
			return decryptedString;
		}
		public static PrivateKey getPrivateKeyFromString(String key) throws Exception{
			BASE64Decoder base64Decoder = new BASE64Decoder();
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(base64Decoder.decodeBuffer(key));
			PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
			return privateKey;
		}
		public String getCertificateAllDetailsForLogin() throws NoSuchFieldException,
		SecurityException, IllegalArgumentException,
		IllegalAccessException, NoSuchMethodException,
				InvocationTargetException {
			String certString = "";
			int count = 0;
			String pubKey = "";
			KeyStore browserKeyStore = null;
			String certDetails = "";
			browserKeyStore = initializeBrowserKeyStore();
			String resultValues ="";
			String aliasnew = null;

			printMessageToConsole(browserName);
			if (browserKeyStore != null) {
				Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
				spiField.setAccessible(true);
				KeyStoreSpi spi = (KeyStoreSpi) spiField.get(browserKeyStore);
				Field entriesField = spi.getClass().getSuperclass()
						.getDeclaredField("entries");
				entriesField.setAccessible(true);
				@SuppressWarnings("rawtypes")
				Collection entries = (Collection) entriesField.get(spi);
				for (Object entry : entries) {
					aliasnew = (String) invokeGetter(entry, "getAlias");
					PrivateKey privateKey = (PrivateKey) invokeGetter(entry,
							"getPrivateKey");
					X509Certificate[] certificateChain = (X509Certificate[]) invokeGetter(
							entry, "getCertificateChain");
					for (X509Certificate current : certificateChain) {
						/*if (certDetails != null
								&& getkeyUsage(current.getKeyUsage()) != "") */
						{
							count++;
							pubKey = this.bASE64Encoder.encode(current
									.getPublicKey().getEncoded());
							pubKey = pubKey.replaceAll("\\s","#");
							certDetails = getX509CertificateDetails(current);
							Map<String, String> valueMap = new HashMap<String, String>();
							valueMap = getMetadata(certDetails);
							certString += "Alias $$ " + aliasnew + "||";
							certString += "Name : "
									+ valueMap.get(CERT_DETAILS.NAME) + "||";
							certString += "Email $$ "
									+ valueMap.get(CERT_DETAILS.EMAIL) + "||";
							certString += "City $$ "
									+ valueMap.get(CERT_DETAILS.CITY) + "||";
							certString += "State $$ "
									+ valueMap.get(CERT_DETAILS.STATE) + "||";
							certString += "Country $$ "
									+ valueMap.get(CERT_DETAILS.COUNTRY) + "||";
							certString += "Expiry Date $$ "
									+ valueMap.get(CERT_DETAILS.EXPIRY_DATE)
									+ "||";
							certString += "Issuer Organization $$ "
									+ valueMap.get(CERT_DETAILS.ISSUER_ORG_NAME)
									+ "||";
							certString += "Issuer Organization Unit $$ "
									+ valueMap.get(CERT_DETAILS.ISSUER_ORG_UNIT)
									+ "||";
							certString += "Key Usage $$ "
									+ getkeyUsage(current.getKeyUsage()) + "||";
							certString += "CNName $$"
									+ valueMap.get(CERT_DETAILS.CN_NAME) + "||";
							certString += "Public Key $$"+"^^ "
									+ pubKey + "||";
							certString += "===";
							break;
						}  
					}
				}
			} else {
				printMessageToConsole("Keystore is NULL");
			}
			return certString;
		}

		
	}