All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.paxml.util.CryptoUtils Maven / Gradle / Ivy

The newest version!
/**
 * This file is part of PaxmlCore.
 *
 * PaxmlCore is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PaxmlCore is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with PaxmlCore.  If not, see .
 */
package org.paxml.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyStore;
import java.security.KeyStore.PasswordProtection;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.util.concurrent.Callable;

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

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.paxml.core.PaxmlRuntimeException;

import com.thoughtworks.xstream.core.util.Base64Encoder;

public class CryptoUtils {

	public static final String DEFAULT_KEY_STORE_NAME = "";
	public static final String DEFAULT_KEY_NAME = "";
	public static final String KEY_STORE_TYPE = "JCEKS";
	public static final String KEY_STORE_EXT = KEY_STORE_TYPE.toLowerCase();
	public static final int KEY_LENGTH_BITS = 128;
	public static final int KEY_LENGTH_BYTES = KEY_LENGTH_BITS / 8;
	public static final String KEY_STORE_FOLDER = "keys";
	public static final String KEY_TYPE = "AES";
	public static final String HASH_TYPE = "SHA-1";
	public static final String KEY_VALUE_ENCODING = "UTF-8";
	private static final String DEFAULT_KEY_PASSWORD = "key_pass";

	private static final RWTaskExecutor keyStoreExecutor = new RWTaskExecutor();

	private static SecretKey getSecretKey(String keyValue) {

		byte[] b;
		try {
			MessageDigest sha = MessageDigest.getInstance(HASH_TYPE);
			b = sha.digest(keyValue.getBytes(KEY_VALUE_ENCODING));
		} catch (Exception e) {
			throw new PaxmlRuntimeException(e);
		}
		byte[] kb = new byte[KEY_LENGTH_BYTES];
		// take the left 16 bytes part of the sha-1
		System.arraycopy(b, 0, kb, 0, kb.length);

		return new SecretKeySpec(kb, KEY_TYPE);

	}

	public static String base64Encode(byte[] data) {
		return new Base64Encoder().encode(data);
	}

	public static byte[] base64Decode(String data) {
		return new Base64Encoder().decode(data);
	}

	public static String hexEncode(byte[] data) {
		return new String(Hex.encodeHex(data));
	}

	public static byte[] hexDecode(String data) {
		try {
			return Hex.decodeHex(data.toCharArray());
		} catch (DecoderException e) {
			throw new PaxmlRuntimeException(e);
		}
	}

	public static byte[] encrypt(String data, String password) {

		SecretKey SecKey = getSecretKey(password);
		try {
			KeyGenerator KeyGen = KeyGenerator.getInstance(KEY_TYPE);
			KeyGen.init(KEY_LENGTH_BITS);

			Cipher cipher = Cipher.getInstance(KEY_TYPE);

			byte[] clear = data.getBytes(KEY_VALUE_ENCODING);

			cipher.init(Cipher.ENCRYPT_MODE, SecKey);
			return cipher.doFinal(clear);
		} catch (Exception e) {
			throw new PaxmlRuntimeException(e);
		}

	}

	public static String decrypt(byte[] data, String password) {
		SecretKey SecKey = getSecretKey(password);
		try {
			KeyGenerator KeyGen = KeyGenerator.getInstance(KEY_TYPE);
			KeyGen.init(KEY_LENGTH_BITS);

			Cipher cipher = Cipher.getInstance(KEY_TYPE);

			cipher.init(Cipher.DECRYPT_MODE, SecKey);
			byte[] clear = cipher.doFinal(data);
			return new String(clear, KEY_VALUE_ENCODING);
		} catch (Exception e) {
			throw new PaxmlRuntimeException(e);
		}
	}

	private static File getKeyStoreFile(String keyStoreName) {
		if (StringUtils.isBlank(keyStoreName)) {
			keyStoreName = DEFAULT_KEY_STORE_NAME;
		}
		String fileName = KEY_STORE_FOLDER + File.separatorChar + keyStoreName + "." + KEY_STORE_EXT;
		File file = PaxmlUtils.getFileUnderPaxmlHome(fileName, false);
		if (file == null) {
			file = PaxmlUtils.getFileUnderUserHome(fileName);
		}
		return file;
	}

	public static void changeKeyStorePassword(String keyStoreName, final String oldPassword, final String newPassword) {
		final File file = getKeyStoreFile(keyStoreName);
		final String key = file.getAbsolutePath();
		keyStoreExecutor.executeWrite(key, new Callable() {

			@Override
			public Void call() throws Exception {
				KeyStore keyStore = getKeyStore(file, oldPassword);
				saveKeyStore(file, newPassword, keyStore);
				return null;
			}
		});
	}

	public static String getKey(String keyStoreName, final String keyStorePassword, final String keyName, final String keyPassword) {
		final File file = getKeyStoreFile(keyStoreName);
		final String key = file.getAbsolutePath();
		return keyStoreExecutor.executeRead(key, new Callable() {

			@Override
			public String call() throws Exception {
				KeyStore keyStore = getKeyStore(file, keyStorePassword);
				return getKey(keyStore, keyName, keyPassword);
			}
		});

	}

	private static String getKey(KeyStore keyStore, String keyName, String keyPassword) {
		if (StringUtils.isBlank(keyName)) {
			keyName = DEFAULT_KEY_NAME;
		}
		if (keyPassword == null) {
			keyPassword = DEFAULT_KEY_PASSWORD;
		}
		PasswordProtection _keyPassword = new PasswordProtection(keyPassword.toCharArray());
		KeyStore.Entry entry;
		try {
			if (!keyStore.containsAlias(keyName)) {
				return null;
			}
			entry = keyStore.getEntry(keyName, _keyPassword);
		} catch (Exception e) {
			throw new PaxmlRuntimeException(e);
		}
		SecretKey key = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
		try {
			return new String(key.getEncoded(), KEY_VALUE_ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw new PaxmlRuntimeException(e);
		}

	}

	public static boolean deleteKeyStore(String keyStoreName) {
		final File file = getKeyStoreFile(keyStoreName);
		return keyStoreExecutor.executeWrite(file.getAbsolutePath(), new Callable() {

			@Override
			public Boolean call() throws Exception {
				return file.delete();
			}

		});

	}

	public static void deleteKey(String keyStoreName, final String keyStorePassword, final String keyName) {
		final File file = getKeyStoreFile(keyStoreName);
		keyStoreExecutor.executeWrite(file.getAbsolutePath(), new Callable() {

			@Override
			public Void call() throws Exception {
				deleteKey(getKeyStore(file, keyStorePassword), keyName);
				return null;
			}

		});
	}

	private static void deleteKey(KeyStore keyStore, String keyName) {
		try {
			if (keyStore.containsAlias(keyName)) {
				keyStore.deleteEntry(keyName);
			}
		} catch (KeyStoreException e) {
			throw new PaxmlRuntimeException(e);
		}
	}

	public static void setKey(String keyStoreName, final String keyStorePassword, final String keyName, final String keyPassword, final String keyValue) {
		final File file = getKeyStoreFile(keyStoreName);
		final String key = file.getAbsolutePath();
		keyStoreExecutor.executeWrite(key, new Callable() {

			@Override
			public Void call() throws Exception {

				KeyStore keyStore = getKeyStore(file, keyStorePassword);
				setKey(keyStore, keyName, keyPassword, keyValue);
				saveKeyStore(file, keyStorePassword, keyStore);
				return null;
			}
		});
	}

	private static void setKey(KeyStore keyStore, String keyName, String keyPassword, String keyValue) {
		if (StringUtils.isBlank(keyName)) {
			keyName = DEFAULT_KEY_NAME;
		}
		if (keyPassword == null) {
			keyPassword = DEFAULT_KEY_PASSWORD;
		}
		try {
			SecretKey secretKey = new SecretKeySpec(keyValue.getBytes(KEY_VALUE_ENCODING), KEY_TYPE);

			KeyStore.SecretKeyEntry keyStoreEntry = new KeyStore.SecretKeyEntry(secretKey);
			PasswordProtection _keyPassword = new PasswordProtection(keyPassword.toCharArray());
			keyStore.setEntry(keyName, keyStoreEntry, _keyPassword);

		} catch (Exception e) {
			throw new PaxmlRuntimeException(e);
		}

	}

	private static void saveKeyStore(final File file, final String password, final KeyStore ks) {
		file.delete();
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			ks.store(fos, password.toCharArray());
		} catch (Exception e) {
			throw new PaxmlRuntimeException("Cannot write to key store file: " + file.getAbsolutePath(), e);
		} finally {
			IOUtils.closeQuietly(fos);
		}

	}

	private static KeyStore getKeyStore(final File file, final String password) {
		final String key = file.getAbsolutePath();

		KeyStore keyStore;

		final char[] pwd = password.toCharArray();
		if (!file.exists()) {
			FileOutputStream fos = null;
			try {
				file.getParentFile().mkdirs();
				fos = new FileOutputStream(file);
				// keystore file not created yet => create it
				keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
				keyStore.load(null, null);
				keyStore.store(fos, pwd);
			} catch (Exception e) {
				throw new PaxmlRuntimeException("Cannot create new key store file: " + key, e);
			} finally {
				IOUtils.closeQuietly(fos);
			}
		}
		FileInputStream fis = null;

		try {
			fis = new FileInputStream(file);
			keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
			// keystore file already exists => load it
			keyStore.load(fis, pwd);

		} catch (Exception e) {
			throw new PaxmlRuntimeException("Cannot read from key store file: " + key, e);
		} finally {
			IOUtils.closeQuietly(fis);
		}

		return keyStore;

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy