/*
* Copyright (C) 2005-2012 NAUMEN. All rights reserved.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
*/
package ru.naumen.servacc.util;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.KeySpec;
import java.util.Base64;
public class StringEncrypter
{
public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
public static final String DES_ENCRYPTION_SCHEME = "DES";
private static final String UTF8 = "UTF-8";
private KeySpec keySpec;
private SecretKeyFactory keyFactory;
private Cipher cipher;
public StringEncrypter(String encryptionScheme, String encryptionKey) throws EncryptionException
{
if (encryptionKey == null)
{
throw new IllegalArgumentException("encryption key was null");
}
final String hash = makeHash(encryptionKey);
if (hash.trim().length() < 24)
{
throw new IllegalArgumentException("encryption key was less than 24 characters");
}
try
{
byte[] keyAsBytes = hash.getBytes(UTF8);
switch (encryptionScheme)
{
case DESEDE_ENCRYPTION_SCHEME:
keySpec = new DESedeKeySpec(keyAsBytes);
break;
case DES_ENCRYPTION_SCHEME:
keySpec = new DESKeySpec(keyAsBytes);
break;
default:
throw new IllegalArgumentException("Encryption scheme not supported: " + encryptionScheme);
}
keyFactory = SecretKeyFactory.getInstance(encryptionScheme);
cipher = Cipher.getInstance(encryptionScheme);
}
catch (InvalidKeyException | UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException e)
{
throw new EncryptionException(e);
}
}
private String makeHash(String encryptionKey) throws EncryptionException
{
try
{
MessageDigest md;
md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(encryptionKey.getBytes());
BigInteger bi = new BigInteger(1, digest);
return String.format("%0" + (digest.length << 1) + "X", bi);
}
catch (NoSuchAlgorithmException e)
{
throw new EncryptionException(e);
}
}
public String encrypt(String unencryptedString) throws EncryptionException
{
if (Util.isEmptyOrNull(unencryptedString))
{
throw new IllegalArgumentException("unencrypted string is empty");
}
try
{
SecretKey key = keyFactory.generateSecret(keySpec);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cleartext = unencryptedString.getBytes(UTF8);
byte[] ciphertext = cipher.doFinal(cleartext);
return Base64.getEncoder().encodeToString(ciphertext);
}
catch (Exception e)
{
throw new EncryptionException(e);
}
}
public String decrypt(String encryptedString) throws EncryptionException
{
if (Util.isEmptyOrNull(encryptedString))
{
throw new IllegalArgumentException("encrypted string is empty");
}
try
{
SecretKey key = keyFactory.generateSecret(keySpec);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] cleartext = Base64.getDecoder().decode(encryptedString);
byte[] ciphertext = cipher.doFinal(cleartext);
return new String(ciphertext, UTF8);
}
catch (Exception e)
{
throw new EncryptionException(e);
}
}
public static class EncryptionException extends Exception
{
private static final long serialVersionUID = -126262601593604355L;
public EncryptionException(Throwable t)
{
super(t);
}
public EncryptionException(String message)
{
super(message);
}
}
}