/*
* Crypto.java
*
* Created on December 27, 2007, 8:39 AM
*
* Copyright 2007, 2008, 2009 Jakim Friant
*
* This file is part of ResetPassword.
*
* ResetPassword is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ResetPassword 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ResetPassword. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cfcc.utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.apache.commons.ssl.OpenSSL;
import org.cfcc.CryptoException;
/**
* A utility class to encrypt or decrypt a password that will be stored in the
* web.xml configuration file.
*
* Uses the not-yet-commons-ssl library from:
* <a href="http://juliusdavies.ca/commons-ssl/index.html">http://juliusdavies.ca/commons-ssl/index.html</a>.
*
* <p>Implemented with examples from:<br>
* <ul>
* <li>http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html
* <li>http://javaboutique.internet.com/resources/books/JavaSec/javasec2_4.html
* <li>http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html
* </ul>
* @author jfriant
*/
public class Crypto {
/** Which algorithm to use for the encryption. */
private static final String ALGORITHM = "aes-128-cbc";
/** key used to encrypt and decrypt the web.xml password */
private static final String default_key = "ResetPassword";
/** Creates a new instance of Crypto */
public Crypto() {
}
/**
* Uses the algorithm name to create as a meaningful tag for the prefix used
* on base64 strings.
* @return a string with the prefix tag enclosed in brackets.
*/
public static String prefix() {
int end = ALGORITHM.indexOf("-");
return "{" + ALGORITHM.substring(0, end).toUpperCase() + "}";
}
/**
* Encrypts a string and returns the ciphertext as a base64 encoded string.
* @param text_in The password (or any string) that is to be encrypted.
* @throws org.cfcc.CryptoException If the encryption fails at any point.
* @return A base64 encoded string with the encrypted text.
*/
public String encrypt(String text_in) throws CryptoException {
String encrypted = null;
try {
byte[] ciphertext = OpenSSL.encrypt(ALGORITHM, default_key.toCharArray(), text_in.getBytes());
encrypted = Crypto.prefix() + new String(ciphertext);
} catch (IOException ex) {
throw new CryptoException(ex.toString());
} catch (GeneralSecurityException ex) {
throw new CryptoException(ex.toString());
}
return encrypted;
}
/**
* Takes a base64 encoded string with the encrypted data and returns the
* cleartext. Removes the algorithm name prefix (if used).
* @param encrypted_data A string with the base64 encoded version of the encrypted string.
* @throws org.cfcc.CryptoException If any part of the decryption process fails.
* @return A string with the cleartext password.
*/
public String decrypt(String encrypted_data) throws CryptoException {
String without_prefix = null;
try {
if (encrypted_data.startsWith(Crypto.prefix())) {
without_prefix = encrypted_data.substring(Crypto.prefix().length());
} else {
without_prefix = encrypted_data;
}
byte[] cleartext = OpenSSL.decrypt(ALGORITHM, default_key.toCharArray(), without_prefix.getBytes());
return new String(cleartext);
} catch (IOException ex) {
throw new CryptoException(ex.toString());
} catch (GeneralSecurityException ex) {
throw new CryptoException(ex.toString());
}
}
}