/**
* Copyright (c) 2000-present 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.kernel.exception.PwdEncryptorException;
import com.liferay.portal.kernel.security.pwd.PasswordEncryptor;
import com.liferay.portal.kernel.security.pwd.PasswordEncryptorUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.DigesterUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.util.DigesterImpl;
import com.liferay.portal.util.PropsValues;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Michael C. Han
*/
public class LegacyAlgorithmAwarePasswordEncryptorTest {
@Before
public void setUp() {
DigesterUtil digesterUtil = new DigesterUtil();
digesterUtil.setDigester(new DigesterImpl());
_compositePasswordEncryptor = new CompositePasswordEncryptor();
_compositePasswordEncryptor.setDefaultPasswordEncryptor(
new DefaultPasswordEncryptor());
List<PasswordEncryptor> passwordEncryptors = new ArrayList<>();
passwordEncryptors.add(new BCryptPasswordEncryptor());
passwordEncryptors.add(new CryptPasswordEncryptor());
passwordEncryptors.add(new NullPasswordEncryptor());
passwordEncryptors.add(new PBKDF2PasswordEncryptor());
passwordEncryptors.add(new SSHAPasswordEncryptor());
_compositePasswordEncryptor.setPasswordEncryptors(passwordEncryptors);
_compositePasswordEncryptor.afterPropertiesSet();
}
@Test
public void testEncryptBCrypt() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_BCRYPT,
"$2a$10$/ST7LsB.7AAHsn/tlK6hr.nudQaBbJhPX9KfRSSzsn.1ij45lVzaK");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_BCRYPT);
}
@Test
public void testEncryptBCryptWith10Rounds() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_BCRYPT + "/10",
"$2a$10$AHEC063zO5wHcovp1JteTukrB5jSWa2OTBkoUx79ItxqKzSBp/Sem");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_BCRYPT + "/10");
}
@Test
public void testEncryptBCryptWith12Rounds() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_BCRYPT + "/12",
"$2a$12$2dD/NrqCEBlVgFEkkFCbzOll2a9vrdl8tTTqGosm26wJK1eCtsjnO");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_BCRYPT + "/12");
}
@Test
public void testEncryptCrypt() throws Exception {
testEncrypt(PasswordEncryptorUtil.TYPE_UFC_CRYPT, "SNbUMVY9kKQpY");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_UFC_CRYPT);
}
@Test
public void testEncryptMD2() throws Exception {
testEncrypt(PasswordEncryptorUtil.TYPE_MD2, "8DiBqIxuORNfDsxg79YJuQ==");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_MD2);
}
@Test
public void testEncryptMD5() throws Exception {
testEncrypt(PasswordEncryptorUtil.TYPE_MD5, "X03MO1qnZdYdgyfeuILPmQ==");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_MD5);
}
@Test
public void testEncryptNONE() throws Exception {
testEncrypt(PasswordEncryptorUtil.TYPE_NONE, "password");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_NONE);
}
@Test
public void testEncryptPBKDF2() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1",
"AAAAoAAB9ADJZ16OuMAPPHe2CUbP0HPyXvagoKHumh7iHU3c");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1");
}
@Test
public void testEncryptPBKDF2With50000Rounds() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1/50000",
"AAAAoAAAw1B+jxO3UiVsWdBk4B9xGd/Ko3GKHW2afYhuit49");
testEncryptDisabled(
PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1/50000");
}
@Test
public void testEncryptPBKDF2With50000RoundsAnd128Key() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1/128/50000",
"AAAAoAAAw1AbW1e1Str9wSLWIX5X9swLn+j5/5+m6auSPdva");
testEncryptDisabled(
PasswordEncryptorUtil.TYPE_PBKDF2 + "WithHmacSHA1/128/50000");
}
@Test
public void testEncryptSHA() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_SHA, "W6ph5Mm5Pz8GgiULbPgzG37mj9g=");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_NONE);
}
@Test
public void testEncryptSHA1() throws Exception {
testEncrypt("SHA-1", "W6ph5Mm5Pz8GgiULbPgzG37mj9g=");
testEncryptDisabled("SHA-1");
}
@Test
public void testEncryptSHA256() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_SHA_256,
"XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_SHA_256);
}
@Test
public void testEncryptSHA384() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_SHA_384,
"qLZLq9CsqRpZvbt3YbQh1PK7OCgNOnW6DyHyvrxFWD1EbFmGYMlM5oDEfRnDB4On");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_SHA_384);
}
@Test
public void testEncryptSSHA() throws Exception {
testEncrypt(
PasswordEncryptorUtil.TYPE_SSHA,
"2EWEKeVpSdd79PkTX5vaGXH5uQ028Smy/H1NmA==");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_SSHA);
}
@Test
public void testEncryptUFCCRYPT() throws Exception {
testEncrypt(PasswordEncryptorUtil.TYPE_UFC_CRYPT, "2lrTlR/pWPUOQ");
testEncryptDisabled(PasswordEncryptorUtil.TYPE_UFC_CRYPT);
}
protected String getAlgorithmHeader(String encryptedPassword) {
int index = encryptedPassword.indexOf(CharPool.CLOSE_CURLY_BRACE);
if (index > 0) {
return encryptedPassword.substring(1, index);
}
return StringPool.BLANK;
}
protected void testEncrypt(String algorithm, String encryptedPassword)
throws PwdEncryptorException {
String legacyEncryptionAlgorithm =
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY;
try {
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY = algorithm;
PasswordEncryptorUtil passwordEncryptorUtil =
new PasswordEncryptorUtil();
passwordEncryptorUtil.setPasswordEncryptor(
LegacyAlgorithmAwarePasswordEncryptor.create(
_compositePasswordEncryptor));
Assert.assertEquals(
encryptedPassword,
PasswordEncryptorUtil.encrypt("password", encryptedPassword));
String newEncryptedPassword = PasswordEncryptorUtil.encrypt(
"password");
Assert.assertNotEquals(
-1,
newEncryptedPassword.indexOf(
"{" + PasswordEncryptorUtil.TYPE_PBKDF2));
newEncryptedPassword = PasswordEncryptorUtil.encrypt(
algorithm, "password", null);
Assert.assertTrue(
algorithm.contains(getAlgorithmHeader(newEncryptedPassword)));
Assert.assertEquals(
newEncryptedPassword,
PasswordEncryptorUtil.encrypt(
"password", newEncryptedPassword));
}
finally {
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY =
legacyEncryptionAlgorithm;
}
}
protected void testEncryptDisabled(String algorithm)
throws PwdEncryptorException {
String legacyEncryptionAlgorithm =
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY;
try {
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY = null;
PasswordEncryptorUtil passwordEncryptorUtil =
new PasswordEncryptorUtil();
passwordEncryptorUtil.setPasswordEncryptor(
LegacyAlgorithmAwarePasswordEncryptor.create(
_compositePasswordEncryptor));
String encryptedPassword = PasswordEncryptorUtil.encrypt(
algorithm, "password", null);
Assert.assertEquals(
-1,
encryptedPassword.indexOf(
"{" + PasswordEncryptorUtil.TYPE_PBKDF2));
Assert.assertEquals(-1, encryptedPassword.indexOf("{" + algorithm));
Assert.assertEquals(
encryptedPassword,
PasswordEncryptorUtil.encrypt(
algorithm, "password", encryptedPassword));
}
finally {
PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY =
legacyEncryptionAlgorithm;
}
}
private CompositePasswordEncryptor _compositePasswordEncryptor;
}