org.xcolab.commons.utils.PwdEncryptor.java Source code

Java tutorial

Introduction

Here is the source code for org.xcolab.commons.utils.PwdEncryptor.java

Source

/**
 * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
 *
 * This library 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 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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.
 */

package org.xcolab.commons.utils;

import com.liferay.portal.PwdEncryptorException;
import com.liferay.portal.kernel.util.*;
import jodd.util.BCrypt;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

/**
 * @author Brian Wing Shun Chan
 * @author Scott Lee
 */
public class PwdEncryptor {

    public static final String PASSWORDS_ENCRYPTION_ALGORITHM = GetterUtil
            .getString(PropsUtil.get(PropsKeys.PASSWORDS_ENCRYPTION_ALGORITHM)).toUpperCase();

    public static final char[] SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"
            .toCharArray();

    public static final String TYPE_BCRYPT = "BCRYPT";

    /**
     * @deprecated {@link #TYPE_UFC_CRYPT}
     */
    public static final String TYPE_CRYPT = "CRYPT";

    public static final String TYPE_MD2 = "MD2";

    public static final String TYPE_MD5 = "MD5";

    public static final String TYPE_NONE = "NONE";

    public static final String TYPE_SHA = "SHA";

    public static final String TYPE_SHA_256 = "SHA-256";

    public static final String TYPE_SHA_384 = "SHA-384";

    public static final String TYPE_SSHA = "SSHA";

    public static final String TYPE_UFC_CRYPT = "UFC-CRYPT";

    public static String encrypt(String clearTextPassword) throws PwdEncryptorException {

        return encrypt(PASSWORDS_ENCRYPTION_ALGORITHM, clearTextPassword, null);
    }

    public static String encrypt(String clearTextPassword, String currentEncryptedPassword)
            throws PwdEncryptorException {

        return encrypt(PASSWORDS_ENCRYPTION_ALGORITHM, clearTextPassword, currentEncryptedPassword);
    }

    public static String encrypt(String algorithm, String clearTextPassword, String currentEncryptedPassword)
            throws PwdEncryptorException {

        if (algorithm.equals(TYPE_BCRYPT)) {
            byte[] saltBytes = _getSaltFromBCrypt(currentEncryptedPassword);

            return encodePassword(algorithm, clearTextPassword, saltBytes);
        } else if (algorithm.equals(TYPE_CRYPT) || algorithm.equals(TYPE_UFC_CRYPT)) {

            byte[] saltBytes = _getSaltFromCrypt(currentEncryptedPassword);

            return encodePassword(algorithm, clearTextPassword, saltBytes);
        } else if (algorithm.equals(TYPE_NONE)) {
            return clearTextPassword;
        } else if (algorithm.equals(TYPE_SSHA)) {
            byte[] saltBytes = _getSaltFromSSHA(currentEncryptedPassword);

            return encodePassword(algorithm, clearTextPassword, saltBytes);
        } else {
            return encodePassword(algorithm, clearTextPassword, null);
        }
    }

    protected static String encodePassword(String algorithm, String clearTextPassword, byte[] saltBytes)
            throws PwdEncryptorException {

        try {
            if (algorithm.equals(TYPE_BCRYPT)) {
                String salt = new String(saltBytes);

                return BCrypt.hashpw(clearTextPassword, salt);
            }
            /*else if (algorithm.equals(TYPE_CRYPT) ||
                 algorithm.equals(TYPE_UFC_CRYPT)) {
                
            return Crypt.crypt(
                saltBytes, clearTextPassword.getBytes(Digester.ENCODING));
            }*/
            else if (algorithm.equals(TYPE_SSHA)) {
                byte[] clearTextPasswordBytes = clearTextPassword.getBytes(Digester.ENCODING);

                // Create a byte array of salt bytes appended to password bytes

                byte[] pwdPlusSalt = new byte[clearTextPasswordBytes.length + saltBytes.length];

                System.arraycopy(clearTextPasswordBytes, 0, pwdPlusSalt, 0, clearTextPasswordBytes.length);

                System.arraycopy(saltBytes, 0, pwdPlusSalt, clearTextPasswordBytes.length, saltBytes.length);

                // Digest byte array

                MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1");

                byte[] pwdPlusSaltHash = sha1Digest.digest(pwdPlusSalt);

                // Appends salt bytes to the SHA-1 digest.

                byte[] digestPlusSalt = new byte[pwdPlusSaltHash.length + saltBytes.length];

                System.arraycopy(pwdPlusSaltHash, 0, digestPlusSalt, 0, pwdPlusSaltHash.length);

                System.arraycopy(saltBytes, 0, digestPlusSalt, pwdPlusSaltHash.length, saltBytes.length);

                // Base64 encode and format string

                return Base64.encode(digestPlusSalt);
            } else {
                return DigesterUtil.digest(algorithm, clearTextPassword);
            }
        } catch (NoSuchAlgorithmException nsae) {
            throw new PwdEncryptorException(nsae.getMessage());
        } catch (UnsupportedEncodingException uee) {
            throw new PwdEncryptorException(uee.getMessage());
        }
    }

    private static byte[] _getSaltFromBCrypt(String bcryptString) throws PwdEncryptorException {

        byte[] saltBytes = null;

        try {
            if (Validator.isNull(bcryptString)) {
                String salt = BCrypt.gensalt();

                saltBytes = salt.getBytes(StringPool.UTF8);
            } else {
                String salt = bcryptString.substring(0, 29);

                saltBytes = salt.getBytes(StringPool.UTF8);
            }
        } catch (UnsupportedEncodingException uee) {
            throw new PwdEncryptorException("Unable to extract salt from encrypted password: " + uee.getMessage());
        }

        return saltBytes;
    }

    private static byte[] _getSaltFromCrypt(String cryptString) throws PwdEncryptorException {

        byte[] saltBytes = null;

        try {
            if (Validator.isNull(cryptString)) {

                // Generate random salt

                Random random = new Random();

                int numSaltChars = SALT_CHARS.length;

                StringBuilder sb = new StringBuilder();

                int x = random.nextInt(Integer.MAX_VALUE) % numSaltChars;
                int y = random.nextInt(Integer.MAX_VALUE) % numSaltChars;

                sb.append(SALT_CHARS[x]);
                sb.append(SALT_CHARS[y]);

                String salt = sb.toString();

                saltBytes = salt.getBytes(Digester.ENCODING);
            } else {

                // Extract salt from encrypted password

                String salt = cryptString.substring(0, 2);

                saltBytes = salt.getBytes(Digester.ENCODING);
            }
        } catch (UnsupportedEncodingException uee) {
            throw new PwdEncryptorException("Unable to extract salt from encrypted password: " + uee.getMessage());
        }

        return saltBytes;
    }

    private static byte[] _getSaltFromSSHA(String sshaString) throws PwdEncryptorException {

        byte[] saltBytes = new byte[8];

        if (Validator.isNull(sshaString)) {

            // Generate random salt

            Random random = new SecureRandom();

            random.nextBytes(saltBytes);
        } else {

            // Extract salt from encrypted password

            try {
                byte[] digestPlusSalt = Base64.decode(sshaString);
                byte[] digestBytes = new byte[digestPlusSalt.length - 8];

                System.arraycopy(digestPlusSalt, 0, digestBytes, 0, digestBytes.length);

                System.arraycopy(digestPlusSalt, digestBytes.length, saltBytes, 0, saltBytes.length);
            } catch (Exception e) {
                throw new PwdEncryptorException(
                        "Unable to extract salt from encrypted password: " + e.getMessage());
            }
        }

        return saltBytes;
    }

}