/**
* This file is part of Faktotum.
*
*
* Faktotum is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Faktotum 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Faktotum.
*
* If not, see <http://www.gnu.org/licenses/>.
*/
package de.romankreisel.faktotum.beans;
import javax.ejb.Stateless;
import org.apache.commons.codec.digest.Crypt;
import org.apache.commons.codec.digest.DigestUtils;
import de.romankreisel.faktotum.exceptions.NotYetImplementedException;
/**
* This class provides the logic to create password hashes and validate
* passwords
*
* @author Roman Kreisel <mail@romankreisel.de>
*/
@Stateless
public class CryptBean {
public enum AUTHENTICATION_SCHEME {
PLAIN, CRYPT, MD5_CRYPT, PLAIN_MD5
}
/**
* Generates a password hash for the given password and authentication
* scheme.
*
* @param password
* the password the be hashed.
* @param authenticationScheme
* the hash algorithm to be used
* @return the password hash
*/
public String crypt(String password, AUTHENTICATION_SCHEME authenticationScheme) {
switch (authenticationScheme) {
case PLAIN:
return this.cryptPlain(password);
case MD5_CRYPT:
return this.cryptMD5Crypt(password);
case PLAIN_MD5:
return this.cryptMD5Plain(password);
case CRYPT:
throw new NotYetImplementedException();
default:
throw new NotYetImplementedException("Unknown authorization scheme " + authenticationScheme.name());
}
}
private String cryptMD5Crypt(String password) {
return Crypt.crypt(password);
}
private String cryptMD5Plain(String password) {
return DigestUtils.md5Hex(password);
}
private String cryptPlain(String password) {
return password;
}
/**
* Verifies a password against a hash, using the given authentication scheme
*
* @param token
* The hash
* @param password
* The password to be verified
* @param authenticationScheme
* the authentication scheme to be used
* @return true if the password is valid, false if not
*/
public boolean verify(String token, String password, AUTHENTICATION_SCHEME authenticationScheme) {
switch (authenticationScheme) {
case PLAIN:
return this.verifyPlain(token, password);
case MD5_CRYPT:
return this.verifyMD5Crypt(token, password);
case PLAIN_MD5:
return this.verifyMD5Plain(token, password);
case CRYPT:
throw new NotYetImplementedException();
default:
throw new NotYetImplementedException("Unknown authorization scheme " + authenticationScheme.name());
}
}
private boolean verifyMD5Crypt(String token, String password) {
String[] parts = token.split("\\$");
if (parts.length != 4) {
return false;
}
if (!parts[1].equals("6")) {
return false;
}
String salt = parts[2];
String myHashString = Crypt.crypt(password, "$6$" + salt + "$");
return myHashString.equals(token);
}
private boolean verifyMD5Plain(String token, String password) {
return token.equalsIgnoreCase(this.cryptMD5Plain(password));
}
private boolean verifyPlain(String token, String password) {
return token.equals(this.cryptPlain(password));
}
}