I'm trying to authenticate users in Mysql database generated by Symfony 2. In Security.yml I have this :
security:
encoders:
"FOS\UserBundle\Model\UserInterface": sha512
In User Table there is 2 fields : Salt and Password.
All passwords are like that :
YqkYUe0pV/TAw12aG2UcBax0hnJNeHez/S0uBGbnDDBxWD2Yeetqm4DfMn/8WKILIeRpM7ncTJ9coYOiNPGeOA==
I'm working on a webservice to authenticate users using PHP. I don't which functions do I have to use to compare plain password with the encrypted ones?
You have to get the password encoder factory from the container.
You can do so like this :
$factory = $container->get('security.encoder_factory'); //$container refers to your container, it can be also $this->container
$user = new Your\Bundle\Entity\User();
$encoder = $factory->getEncoder($user);
$encodedPassword = $encoder->encodePassword($nonEncodedPassword, $user->getSalt());
This should be enough. Of course you can set "by hand" the second encodePassword parameter as its the salt used to encode all paswords. It's usually defined in your user implementation class, that's why we give here an entity instancied object.
This is the class that handles the sha512 encryption in Symfony2
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php
Related
In setting up a "change password" feature for a site I have a secondary password entry (where you need to enter your password again before you can change it).
I need to be able to check the user's current password (hashed using Bcrypt) against the password that has been entered.
In my controller action I have:
$currentPassword = $request->request->get('password');
$encoder = $this->container->get('security.password_encoder');
$encodedPassword = $encoder->encodePassword($user, $currentPassword);
if($encodedPassword == $user->getPassword()) { // these don't ever match.
// ...
}
encodePassword(...) produces a digest of the password that was entered, but it's not the same as the saved password (the plaintext is the same), so I'm thinking that a different salt is being applied and therefore producing the mismatch.
Since Bcrypt incorporates the salt in the password digest, I'm not saving it anywhere.
How can I check if the entered plaintext password matches the stored Bcrypt digest in Symfony 3?
I am not using FOSUserBundle.
You can compare the $currentPassword password with the stored one using the isPasswordValid method of the encoder service:
$encoderService = $this->container->get('security.password_encoder')
and then pass the user object as first argument of the method:
$match = $encoderService->isPasswordValid($userObject, $currentPassword)
that will returns true if the comparison match or false otherwise.
What type of hashing algorithm is used by default for passwords in Laravel. If we want to change the password in the database then how can we identify the hash type of the password?
According to Laravel Documentation :
The Laravel Hash facade provides secure Bcrypt hashing for storing
user passwords. If you are using the AuthController controller that is
included with your Laravel application, it will be take care of
verifying the Bcrypt password against the un-hashed version provided
by the user.
Likewise, the user Registrar service that ships with Laravel makes the
proper bcrypt function call to hash stored passwords.
Hashing A Password Using Bcrypt
$password = Hash::make('secret');
You may also use the bcrypt helper function:
$password = bcrypt('secret');
Verifying A Password Against A Hash
if (Hash::check('secret', $hashedPassword))
{
// The passwords match...
}
Checking If A Password Needs To Be Rehashed
if (Hash::needsRehash($hashed))
{
$hashed = Hash::make('secret');
}
You can also use laravel/tinker to update/create/delete/etc data in the DB table from console, for example:
php artisan tinker
>>$user = App\Models\User::find(2);// or User::find(2)find user with id 2
>>$user->password = bcrypt('test83403'); //change password
>>$user->save(); //save the new change
I've been given the task of transferring a user database from one FOSUserBundle/Symfony project to another.
My sample user from the old project has been transferred over to the new project containing all the same fields [ salt, password, etc ], yet I'm unable to login using the same username / password combination.
What else goes into the password storage in FOSUserBundle that would make the password + salt combination invalid between projects, and how can I transfer the raw data of the old project into the new project.
My input is a JSON file with all the user table details. I am importing this through PHP, and creating and persisting user objects in a loop without using fos_user.user_manager.
foreach ($obj as $userData) {
if (isset($userData['personalDetails'])) {
if (isset($userData['personalDetails']['firstName'])) {
/** #var User $user */
$user = new User();
$user->setId($userData['id']);
$user->setSalt($userData['salt']);
$user->setPassword($userData['password']);
$user->setUsername($userData['email']);
$user->setEmail($userData['email']);
$user->setEnabled($userData['enabled']);
$user->setExpired($userData['expired']);
$user->getPersonalDetails()->setFirstName($userData['personalDetails']['firstName']);
$user->getPersonalDetails()->setLastName($userData['personalDetails']['lastName']);
$user->setFacebookId($userData['facebookId']);
$user->setFacebookAccessToken($userData['facebookAccessToken']);
$user->setGoogleId($userData['googleId']);
$user->setGoogleAccessToken($userData['googleAccessToken']);
$this->getDoctrine()->getManager()->persist($user);
}
}
}
You can use the same table (FOSUSER) with your new project or just dump your table and move it to your new database.
If you do that, you have to keep the same "Encoder configuration" on the security as the old project.
The UserPassword only need the salt, the PlainPassword and user the encoded user to create the hashed password. If you have the same configuration in the configuration in the new project like the old one everything will be ok. Hope I help you .. Let us know.
//Security.yml
security:
encoders:
Site\UserBundle\Entity\User: sha512
FOS\UserBundle\Model\UserInterface: sha512
I'm using DynamoDB for my application so the doctrine ORM isn't an option for me when it comes to authentication.
I've created a basic user provider and have it working perfectly when using a sha1 hash, however I'm completely stuck / don't understand how to get it working with salt.
FYI: My code is based on this guide from the manual
Code:
Once the 'new user' form has been submitted a grab the raw data and do the following then persist to the DB - this works fine:
$salt = '79fdshjh408hjhgd87r5438ujl';
$password = base64_encode(sha1($rawPassword.'{'.$salt.'}'));
When authenticating I have a 'userProvider' that requests the users details based on username from the DB - this also works fine and I'm returned all the details
//WebserviceUserProvider.php
$username = $userData['userName'];
$password = $userData['password'];
$roles[0] = 'ROLE_ADMIN';
$salt = '79fdshjh408hjhgd87r5438ujl';
return new WebserviceUser($username, $password, $salt, $roles);
the WebserviceUser file is a direct copy of the one in the docs:
security.yml
security:
encoders:
HvH\SecurityBundle\Security\WebserviceUser:
algorithm: sha1
iterations: 1
encode_as_base64: true
If anyone could point me in the right direction, it would be much appreciated.
Thank you
I'm using Zend_Auth with setCredentialTreatment to set the hash method and salt. I see all examples doing something like this, where the salt seems to be inserted as a text.
->setCredentialTreatment('SHA1(CONCAT(?,salt))'
but my salt is stored in the database. I could retrieve it first then use it in setCredentialTreatment but is there a way I could define it directly as a field name, so setCredentialTreatment would know to get it from that field? sort of like the way we define the field name for the username or password
->setCredentialColumn('password')
A side issue I'm having is that I'd like to use SHA512 not SHA1. Is this possible or is it not available? All the examples I see using SHA1.
I should say I'm fairly new to zend and am porting an existing application, so please go easy on me with the answers.
The example you've given does use the salt as stored in the database. It will work as long as the salt is stored in each row in a field called 'salt'. If the salt was not in the DB and in a PHP variable instead, the code would be something more like:
->setCredentialTreatment("SHA1(CONCAT(?, '$salt'))")
As for using SHA512, this might be a little trickier. Assuming you're using MySQL, SHA1() in this case is a MySQL function, and MySQL does not have a function for SHA512 as far as I can tell, and neither does PHP (edit: I was wrong about the latter, see comments). So you'll have to implement your own PHP SHA512 function, load the salt for the user out of the DB first, hash the result and not do anything to the variable in setCredentialTreatment.
As the other answer suggested you might want to write your own Zend_Auth_Adapter for this. An auth adapter is a class that handles authentication, presumably at the moment you're using Zend_Auth_Adapter_DbTable. You can find some more info about auth adapters in the manual: http://framework.zend.com/manual/en/zend.auth.introduction.html
Here's an example:
class My_Auth_Adapter extends Zend_Auth_Adapter_DbTable
{
public function authenticate()
{
// load salt for the given identity
$salt = $this->_zendDb->fetchOne("SELECT salt FROM {$this->_tableName} WHERE {$this->_identityColumn} = ?", $this->_identity);
if (!$salt) {
// return 'identity not found' error
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, $this->_identity);
}
// create the hash using the password and salt
$hash = ''; // SET THE PASSWORD HASH HERE USING $this->_credential and $salt
// replace credential with new hash
$this->_credential = $hash;
// Zend_Auth_Adapter_DbTable can do the rest now
return parent::authenticate();
}
}
You can write your own Zend_Auth_Adapter.