留言板

Liferay authentication and Password encryption

Mansi Mistry,修改在8 年前。

Liferay authentication and Password encryption

Junior Member 帖子: 31 加入日期: 14-9-30 最近的帖子
Hi,

We are trying to emulate the password encryption algorithm used by Liferay, but we are unable to do so. We need to provide authentication of user against the Liferay credentials saved in LIferay db.

We are trying to use CAS for authorization and need an authentication source which in our case is Liferay. We want to write custom code that authenticates using the username/password stored in Liferay DB through a JDBC call.

Currently, when we try to emulate the password encryption and try to match it against the existing entry in DB, but its a failure. The encrypted passwords do not match. What is correct way to achieve this? We tried to dig into the Liferay code and understand the steps followed to achieve encryption but seems we might have missed out on something.

Our end goal is to use the Liferay authentication mechanism.

Any help or pointers on this would be helpful. Thanks in advance!
thumbnail
Olaf Kock,修改在8 年前。

RE: Liferay authentication and Password encryption

Liferay Legend 帖子: 6403 加入日期: 08-9-23 最近的帖子
  • Which version?
  • Can you show the code that you wrote? Which code did you base it on?
  • Did you configure the password encryption/hashing algorithm to something other than the default?
  • Did you honor the "legacy" algorithm? There might be two different hash algorithms in use at the same time if you upgraded from an older version that used another password hashing algorithm
Mansi Mistry,修改在8 年前。

RE: Liferay authentication and Password encryption

Junior Member 帖子: 31 加入日期: 14-9-30 最近的帖子
Olaf Kock:
  • Which version?
  • Can you show the code that you wrote? Which code did you base it on?
  • Did you configure the password encryption/hashing algorithm to something other than the default?
  • Did you honor the "legacy" algorithm? There might be two different hash algorithms in use at the same time if you upgraded from an older version that used another password hashing algorithm




Which version?
WE are using liferay_6.2.x_CE version

Can you show the code that you wrote? Which code did you base it on?
We are using liferay '6.2.1' jar files.
- util-java-6.2.1.jar
- portal-impl-6.2.1.jar
- portal-service-6.2.1.jar
We are using com.liferay.portal.security.pwd.PBKDF2PasswordEncryptor class code to encrypt our password
Method_Name = doEncrypt(String algorithm, String plainTextPassword,String encryptedPassword)
Did you configure the password encryption/hashing algorithm to something other than the default?
We are using default algorithm "PBKDF2WITHHMACSHA1/160/128000" in liferay. We have not customized any encryption/hashing algo.

Did you honor the "legacy" algorithm? There might be two different hash algorithms in use at the same time if you upgraded from an older version that used another password hashing algorithm
There is no upgrade scenario.


Problem we are facing:

We want to use CAS as authentication and lifearay db as auth db for CAS. We have configured CAS to use liferay DB and customized encryption for password. Custom encryption is written using liferay encryption class (PBKDF2PasswordEncryptor) mentioned above.


package com.test;

import java.nio.ByteBuffer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

import com.liferay.portal.PwdEncryptorException;
import com.liferay.portal.kernel.io.BigEndianCodec;
import com.liferay.portal.kernel.util.Base64;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.Validator;

public class LiferayPasswordUtil {
	  private static String algorithm = "PBKDF2WITHHMACSHA1/160/128000";
	  public String doEncrypt(String password) throws Exception {
	    	
	    	return this.doEncrypt(algorithm, password, null);
	    }
	  public String[] getSupportedAlgorithmTypes() {
		  
			return new String[] { "PBKDF2WithHmacSHA1/160/128000" };
		}

		protected  String doEncrypt(String algorithm, String plainTextPassword,
				String encryptedPassword) throws PwdEncryptorException {

			try {
				PBKDF2EncryptionConfiguration pbkdf2EncryptionConfiguration = new PBKDF2EncryptionConfiguration();

				pbkdf2EncryptionConfiguration.configure(algorithm,
						encryptedPassword);

				byte[] saltBytes = pbkdf2EncryptionConfiguration.getSaltBytes();

				PBEKeySpec pbeKeySpec = new PBEKeySpec(
						plainTextPassword.toCharArray(), saltBytes,
						pbkdf2EncryptionConfiguration.getRounds(),
						pbkdf2EncryptionConfiguration.getKeySize());

				String algorithmName = algorithm;

				int index = algorithm.indexOf(CharPool.SLASH);

				if (index > -1) {
					algorithmName = algorithm.substring(0, index);
				}

				SecretKeyFactory secretKeyFactory = SecretKeyFactory
						.getInstance(algorithmName);

				SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);

				byte[] secretKeyBytes = secretKey.getEncoded();

				ByteBuffer byteBuffer = ByteBuffer.allocate(2 * 4
						+ saltBytes.length + secretKeyBytes.length);

				byteBuffer.putInt(pbkdf2EncryptionConfiguration.getKeySize());
				byteBuffer.putInt(pbkdf2EncryptionConfiguration.getRounds());
				byteBuffer.put(saltBytes);
				byteBuffer.put(secretKeyBytes);
				System.out.println("++++++++++++++++++ encoded ++++++++" + Base64.encode(byteBuffer.array()));
				return Base64.encode(byteBuffer.array());
			}
			catch (Exception e) {
				throw new PwdEncryptorException(e.getMessage(), e);
			}
		}

		private static final int _KEY_SIZE = 160;

		private static final int _ROUNDS = 128000;

		private static final int _SALT_BYTES_LENGTH = 8;

		private static Pattern _pattern = Pattern
				.compile("^.*/?([0-9]+)?/([0-9]+)$");

		private class PBKDF2EncryptionConfiguration {

			public void configure(String algorithm, String encryptedPassword)
					throws PwdEncryptorException {

				if (Validator.isNull(encryptedPassword)) {
					Matcher matcher = _pattern.matcher(algorithm);

					if (matcher.matches()) {
						_keySize = GetterUtil.getInteger(matcher.group(1),
								_KEY_SIZE);

						_rounds = GetterUtil.getInteger(matcher.group(2), _ROUNDS);
					}

					BigEndianCodec.putLong(_saltBytes, 0,
							SecureRandomUtil.nextLong());
				} else {
					byte[] bytes = new byte[16];

					try {
						byte[] encryptedPasswordBytes = Base64
								.decode(encryptedPassword);

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

					ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);

					_keySize = byteBuffer.getInt();
					_rounds = byteBuffer.getInt();

					byteBuffer.get(_saltBytes);
				}
			}

			public int getKeySize() {
				return _keySize;
			}

			public int getRounds() {
				return _rounds;
			}

			public byte[] getSaltBytes() {
				return _saltBytes;
			}

			private int _keySize = _KEY_SIZE;
			private int _rounds = _ROUNDS;
			private byte[] _saltBytes = new byte[_SALT_BYTES_LENGTH];

		}
	    
}




We are passing plane text and algorithm to doEncrypt method and previous encrypted password as null. Method returns encrypted password but it does not match encrypted/hashed password in db.
Is there any way to get this encrypted pass same as db?

We debugged the deployed liferay code to check its authentication. Algorithm we are using is same as liferay. We are not able to get exact salt for encryption.
Passing null value for encryptedPassword parameter in doEncrypt method leads to random salt generation (which ideally happens when the encryption happens for the first time). But in our case we require the same salt value that was generated for the first time to perform encryption/hashing.
Is there any other way to do the encryption/hashing just as Liferay default?
thumbnail
Olaf Kock,修改在8 年前。

RE: Liferay authentication and Password encryption

Liferay Legend 帖子: 6403 加入日期: 08-9-23 最近的帖子
How about you debug a login procedure in Liferay and in your CAS implementation? Or just log what goes in&out in the various methods.
It might be the configuration with proper salt that's missing.
thumbnail
Jack Bakker,修改在8 年前。

RE: Liferay authentication and Password encryption

Liferay Master 帖子: 978 加入日期: 10-1-3 最近的帖子
Mansi Mistry:

We want to use CAS as authentication and lifearay db as auth db for CAS. We have configured CAS to use liferay DB and customized encryption for password


I have a Liferay v6.2 which uses first CAS against OpenLDAP and if that fails looks to Liferay user_ in db itself (for accounts that might be only in Liferay but not in LDAP)

We chose to go with SHA adding to portal-ext.properties. In my case an upgrade was involved so there were other conveniences in this setting.

passwords.encryption.algorithm.legacy=SHA

but mine doesn't sound like exactly same use case is same as yours where you seem to require PBKDF2

Tomas might have some useful ideas here:
https://www.liferay.com/community/forums/-/message_boards/message/37036189?_19_threadView=tree
Piyush Singh,修改在8 年前。

RE: Liferay authentication and Password encryption

New Member 帖子: 16 加入日期: 14-2-10 最近的帖子
Hi Mansi,

I am also facing the same problem. Did you manage to solve it?

Regards,
Piyush SIngh
Mansi Mistry,修改在8 年前。

RE: Liferay authentication and Password encryption

Junior Member 帖子: 31 加入日期: 14-9-30 最近的帖子
Not really. From what I understand we need to somehow query the Liferay database the hash and obtain the salt value. Only once we have the salt value with us we can get the same hash value and the passwords can be matched.
thumbnail
Tomas Polesovsky,修改在7 年前。

RE: Liferay authentication and Password encryption

Liferay Master 帖子: 676 加入日期: 09-2-13 最近的帖子
Hi guys,

if you want to check the password, you need to provide:
1, plain-text password provided by the user
2, existing hash of the password

The implementation needs data from the hash to correctly initialize PBEKeySpec, like key size, number of iterations and the salt. Only then it can create hash of the password the same way and come to the same result.
lee zach,修改在7 年前。

RE: Liferay authentication and Password encryption

New Member 帖子: 3 加入日期: 15-7-18 最近的帖子
excellent! fixed my problem!!