package eu.dnetlib.enabling.aas.utils;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * Utility class for creating asymmetric keys, encrypting and decrypting.
 * @author mhorst
 *
 */
public abstract class SecurityUtils {

	public static final String DEFAULT_SYM_ALGORITHM 	= "DES";
	public static final int DEFAULT_SYM_KEYSIZE 		= 64;
	
	public static final String DEFAULT_ASYM_ALGORITHM 	= "RSA";
	public static final int DEFAULT_ASYM_KEYSIZE 		= 512;
	public static final String DEFAULT_ASYM_TRANSFORMATION = "RSA/NONE/PKCS1PADDING";
	
	static {
		Security.addProvider(new BouncyCastleProvider());
	}

	private SecurityUtils() {
		
	}
	
	/**
	 * Generates random key pair.
	 * @param asymAlgorithm
	 * @param asymKeysize
	 * @return KeyPair
	 * @throws NoSuchAlgorithmException
	 */
	public static KeyPair generateKeyPair(String asymAlgorithm, int asymKeysize) 
		throws NoSuchAlgorithmException {
		KeyPairGenerator generator = KeyPairGenerator.getInstance(asymAlgorithm);
		SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
		generator.initialize(asymKeysize,random);
		return generator.generateKeyPair();
	}
	
	/**
	 * Generates secret key.
	 * @param symAlgorithm
	 * @param symKeysize
	 * @return secret key
	 * @throws NoSuchAlgorithmException
	 */
	public static SecretKey generateSecretKey(String symAlgorithm, int symKeysize) 
		throws NoSuchAlgorithmException {
		KeyGenerator generator = KeyGenerator.getInstance(symAlgorithm);
		SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
		generator.init(symKeysize, random);
		return generator.generateKey();
	}

	
	/**
	 * Encrypts input data with public key given as parameter.
	 * @param inpBytes
	 * @param key
	 * @param asymTransformation
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] inpBytes, PublicKey key, String asymTransformation)
			throws Exception {
		Cipher cipher = Cipher.getInstance(asymTransformation);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(inpBytes);
	}

	/**
	 * Decrypts input data with private key given as parameter.
	 * @param inpBytes
	 * @param key
	 * @param asymTransformation
	 * @return
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] inpBytes, PrivateKey key, String asymTransformation)
			throws Exception {
		Cipher cipher = Cipher.getInstance(asymTransformation);
		cipher.init(Cipher.DECRYPT_MODE, key);
		return cipher.doFinal(inpBytes);
	}

}
