package net.curisit.securis.utils; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import net.curisit.securis.SeCurisException; import org.apache.commons.net.util.Base64; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; //import net.curisit.common.ui.Dialogs; public class CryptoHelper { private static final Logger log = LogManager.getLogger(SignatureHelper.class); private static final String KEY_FACTORY = "PBEWITHHMACSHA1"; private static final String PPROVIDER = "BC"; private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; private static CryptoHelper singleton = new CryptoHelper(); private String passPhrase = null; private CryptoHelper() { } public static CryptoHelper getInstance() { return singleton; } /** * Encrypts a given text with AES algorithm * * @param plainText * @return The encrypted text in Base64 */ public String encrypt(String plainText) throws SeCurisException { return encrypt(plainText, this.passPhrase); } public String encrypt(String plainText, String pass) throws SeCurisException { Cipher aes; try { aes = Cipher.getInstance(CIPHER_ALGORITHM); byte[] salt = getSalt(); aes.init(Cipher.ENCRYPT_MODE, getSecretKey(salt, pass)); byte[] ciphertext = aes.doFinal(plainText.getBytes("utf-8")); return Base64.encodeBase64String(salt) + "\n" + Base64.encodeBase64String(ciphertext); } catch (NoSuchAlgorithmException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (NoSuchPaddingException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (InvalidKeyException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (IllegalBlockSizeException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (BadPaddingException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (UnsupportedEncodingException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } } /** * Encrypts a given text with AES algorithm * * @param plainText * in Base64 * @return */ public String decript(String ciphertext) throws SeCurisException { return decript(ciphertext, this.passPhrase); } public String decript(String ciphertext, String pass) throws SeCurisException { Cipher aes; try { aes = Cipher.getInstance(CIPHER_ALGORITHM); int sep = ciphertext.indexOf('\n'); if (sep == -1) throw new SeCurisException("Unknown format ciphered text"); byte[] salt = Base64.decodeBase64(ciphertext.substring(0, sep)); aes.init(Cipher.DECRYPT_MODE, getSecretKey(salt, pass)); byte[] encryptedBytes = Base64.decodeBase64(ciphertext.substring(sep + 1)); String cleartext = new String(aes.doFinal(encryptedBytes)); return cleartext; } catch (NoSuchAlgorithmException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (NoSuchPaddingException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (InvalidKeyException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (IllegalBlockSizeException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } catch (BadPaddingException e) { log.error("Error decrypting text", e); throw new SeCurisException("Error decrypting text", e); } } private byte[] getSalt() throws SeCurisException { byte[] salt = new byte[20]; new SecureRandom().nextBytes(salt); return salt; } private SecretKeySpec getSecretKey(byte[] salt, String pass) throws SeCurisException { String passPhrase = pass.replace('a', 'รค'); try { int iterations = 10000; SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_FACTORY, PPROVIDER); SecretKey tmp = factory.generateSecret(new PBEKeySpec(passPhrase.toCharArray(), salt, iterations, 128)); byte[] key = Arrays.copyOf(tmp.getEncoded(), 16); SecretKeySpec spec = new SecretKeySpec(key, "AES"); return spec; } catch (NoSuchAlgorithmException e) { log.error("Error generation secret key", e); throw new SeCurisException("Error generation secret key", e); } catch (InvalidKeySpecException e) { log.error("Error generation secret key", e); throw new SeCurisException("Error generation secret key", e); } catch (NoSuchProviderException e) { log.error("Error generation secret key", e); throw new SeCurisException("Error generation secret key", e); } } }