com.liferay.portal.security.pwd.PwdEncryptor.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.security.pwd.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 com.liferay.portal.security.pwd;

/*
import com.liferay.portal.PwdEncryptorException;
import com.liferay.portal.kernel.util.Base64;
import com.liferay.portal.kernel.util.Digester;
import com.liferay.portal.kernel.util.DigesterUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.util.PropsUtil;
*/
import com.github.davidcarboni.cryptolite.ByteArray;
import org.apache.commons.lang.StringUtils;

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import java.util.Random;

//import jodd.util.BCrypt;

//import org.vps.crypt.Crypt;

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

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

    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 final char[] saltChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"
            .toCharArray();

    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*/public static String encodePassword(String algorithm, String clearTextPassword, byte[] saltBytes)
            throws PwdEncryptorException {

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

                return null; // BCrypt.hashpw(clearTextPassword, salt);
            } else if (algorithm.equals(TYPE_CRYPT) || algorithm.equals(TYPE_UFC_CRYPT)) {

                return null; // Crypt.crypt(
                //saltBytes, clearTextPassword.getBytes(Digester.ENCODING));
            } else if (algorithm.equals(TYPE_SSHA)) {
                byte[] clearTextPasswordBytes = clearTextPassword.getBytes("UTF8");//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 ByteArray.toBase64String(digestPlusSalt);
                //return Base64.encode(digestPlusSalt);
            } else {
                return null; // 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)) {
            if (StringUtils.isEmpty(bcryptString)) {
                String salt = null; // BCrypt.gensalt();

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

                //saltBytes = salt.getBytes(StringPool.UTF8);
                saltBytes = salt.getBytes("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)) {
            if (StringUtils.isEmpty(cryptString)) {

                // Generate random salt

                Random random = new Random();

                int numSaltChars = saltChars.length;

                StringBuilder sb = new StringBuilder();

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

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

                String salt = sb.toString();

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

                // Extract salt from encrypted password

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

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

        return saltBytes;
    }

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

        byte[] saltBytes = new byte[8];

        //if (Validator.isNull(sshaString)) {
        if (StringUtils.isEmpty(sshaString)) {

            // Generate random salt

            Random random = new SecureRandom();

            random.nextBytes(saltBytes);
        } else {

            // Extract salt from encrypted password

            try {
                byte[] digestPlusSalt = ByteArray.fromBase64String(sshaString);
                //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;
    }

    /**
     * A few lines to test we've successfully got the Liferay code working in isolation.
     * @param args Not used.
     * @throws PwdEncryptorException Said no method call ever.
     */
    public static void main(String[] args) throws PwdEncryptorException {
        String password = com.github.davidcarboni.cryptolite.Random.password(8);
        System.out.println("password = " + password);
        String hash = encrypt(password);
        System.out.println("hash = " + hash);
        String verify = encrypt(password, hash);
        System.out.println("verify = " + verify);
        boolean ok = StringUtils.equals(hash, verify);
        System.out.println("ok = " + ok);
    }

}