package org.atricore.idbus.capabilities.atricoreid.common;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* @author <a href=mailto:sgonzalez@atricore.org>Sebastian Gonzalez Oyuela</a>
*/
public class AESTokenEncrypter implements TokenEncrypter {
private String base64key;
private String encryptAlg = "AES";
public String encrypt(String tokenValue) throws AtricoreIDEncryptionException {
try {
return encryptAES(tokenValue, base64key);
} catch (Exception e) {
throw new AtricoreIDEncryptionException(e);
}
}
public String decrypt(String encryptedTokenValue) throws AtricoreIDEncryptionException {
try {
return decryptAES(encryptedTokenValue, base64key);
} catch (Exception e) {
throw new AtricoreIDEncryptionException(e);
}
}
/**
* This generates a 128 AES key.
*
* @throws java.security.NoSuchAlgorithmException
*/
public static SecretKeySpec generateAESKey() throws NoSuchAlgorithmException {
SecretKeySpec skeySpec;
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
skeySpec = new SecretKeySpec(key, "AES");
return skeySpec;
}
/**
* Creates an ecnrypted string using AES of the given message. The string is encoded using base 64.
*/
protected String encryptAES(String msg, String myKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// use SHA-1 to generate a hash from your key and trim the result to 128 bit (16 bytes)
byte[] key = toAESKey(myKey);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] text = cipher.doFinal(msg.getBytes());
return encodeBase64(text);
}
/**
* Decrypts the given text using AES
*/
protected String decryptAES(String base64text, String myKey ) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// use SHA-1 to generate a hash from your key and trim the result to 128 bit (16 bytes)
byte[] key = toAESKey(myKey);
SecretKeySpec skeySpec = new SecretKeySpec(key, encryptAlg);
Cipher cipher = Cipher.getInstance(encryptAlg);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] text = decodeBase64(base64text);
byte[] msg = cipher.doFinal(text);
return new String (msg);
}
protected byte[] toAESKey(String myKey) throws UnsupportedEncodingException, NoSuchAlgorithmException {
// use SHA-1 to generate a hash from your key and trim the result to 128 bit (16 bytes)
byte[] key = myKey.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
return key;
}
/**
* Base64 encoding. Charset ISO-8859-1 is assumed.
*/
public static String encodeBase64(byte[] bytes) throws UnsupportedEncodingException {
byte[] enc = Base64.encodeBase64(bytes);
return new String(enc);
}
/**
* Base64 encoding. Charset ISO-8859-1 is assumed.
*/
public static byte[] decodeBase64(String text) throws UnsupportedEncodingException {
byte[] bin = Base64.decodeBase64(text.getBytes());
return bin;
}
/**
* Base16 encoding (HEX).
*/
public static String encodeBase16(byte[] bytes) {
StringBuffer sb = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
// top 4 bits
char c = (char) ((b >> 4) & 0xf);
if (c > 9)
c = (char) ((c - 10) + 'a');
else
c = (char) (c + '0');
sb.append(c);
// bottom 4 bits
c = (char) (b & 0xf);
if (c > 9)
c = (char) ((c - 10) + 'a');
else
c = (char) (c + '0');
sb.append(c);
}
return sb.toString();
}
public String getBase64key() {
return base64key;
}
public void setBase64key(String base64key) {
this.base64key = base64key;
}
public String getEncryptAlg() {
return encryptAlg;
}
public void setEncryptAlg(String encryptAlg) {
this.encryptAlg = encryptAlg;
}
}