/** * 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)); } }