13

I'm new to Symfony2 and I have maybe a simple question about encoding my user passwords in my DB.

I'd like to encode and store in DB my users' password that way:

encoded_password = salt . sha1 ( salt . raw_password )

I've found various encoders (sha1, sha512, plaintext), I saw that with plaintext I have in my DB raw_password{salt} but I'm still not comfortable with signin/login/getSalt() method in Symfony2.

If you could give me a lift on that (please, assume I do not want to use an existing bundle for UserManagement, I'd like to make my own) it would be AWESOME!

Thanks

EDIT:

I could do that in my signinAction():

$salt = substr(md5(time()),0,10);
$pwd = $encoder->encodePassword($user->getPassword(), $salt);
$user->setPassword($salt.$pwd);

I could do that in my getSalt():

return substr($this->password,0,10);

But I currently have only that in my loginAction(): (see here: http://symfony.com/doc/current/book/security.html)

// src/Acme/SecurityBundle/Controller/Main;
namespace Acme\SecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;

class SecurityController extends Controller
{
    public function loginAction()
    {
        $request = $this->getRequest();
        $session = $request->getSession();

        // get the login error if there is one
        if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
        } else {
            $error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
        }

        return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
            // last username entered by the user
            'last_username' => $session->get(SecurityContext::LAST_USERNAME),
            'error'         => $error,
        ));
    }
}

How can I tell Symfony2 to check the password during the login action the way I need? (curently doing encode(password,salt) and not salt.encode(password,salt)

6
  • 1
    "I'm still not comfortable with signin/login/getSalt() method in Symfony2" - about what specifically? Would be good to know to answer your question. Commented Oct 24, 2011 at 16:42
  • That means that I see how to implement this behaviour on my Signin Controller, but I currently use the Sf2 default loginAction and do not know how to implement it in that one. Commented Oct 24, 2011 at 16:45
  • To which bundle are you referring to? Commented Oct 24, 2011 at 17:01
  • Hey @hakre, I put some code in my question. Hope it will help you to understand my problem. Thanks a lot Commented Oct 25, 2011 at 7:32
  • 2
    Check out my bundle: github.com/elnur/ElnurBlowfishPasswordEncoderBundle. It provides real encryption — not just hashing. Commented Nov 28, 2011 at 13:55

3 Answers 3

48

To make it simple: you have to create and add a new Service, add it to your bundle and specity that the User class will use it. First you have to implement your own password encoder:

namespace Acme\TestBundle\Service;

use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

class Sha256Salted implements PasswordEncoderInterface
{

    public function encodePassword($raw, $salt)
    {
        return hash('sha256', $salt . $raw); // Custom function for password encrypt
    }

    public function isPasswordValid($encoded, $raw, $salt)
    {
        return $encoded === $this->encodePassword($raw, $salt);
    }

}

Then you'll add the service definition and you want to specify to use your custom encoder for the class User. In TestBundle/Resources/config/services.yml you add custom encoder:

services:
    sha256salted_encoder:
        class: Acme\TestBundle\Service\Sha256Salted

and in app/config/security.yml you can therefore specify your custom class as default encoder (for Acme\TestBundle\Entity\User class):

 encoders:
   Acme\TestBundle\Entity\User:
     id: acme.test.sha256salted_encoder

Of course, salt plays a central role in password encryption. Salt is unique and is stored for each user. The class User can be auto-generated using YAML annotations (table should - of course - contain fields username, password, salt and so on) and should implement UserInterface.

Finally you can use it (controller code) when you have to create a new Acme\TestBundle\Entity\User:

// Add a new User
$user = new User();
$user->setUsername = 'username';
$user->setSalt(uniqid(mt_rand())); // Unique salt for user

// Set encrypted password
$encoder = $this->container->get('acme.test.sha256salted_encoder')
  ->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);
Sign up to request clarification or add additional context in comments.

3 Comments

Perfect!! You made my day! I was desperate loosing all my passwords during migration between my old solution and the new one using sf2 ;)
Hi, this works perfect to create a account. But how can I use to login my user?
Because the user is not going to be authenticated. How can I do it?
2

Thank you gremo, There's a small problem in the last snippet of your code, when using the service we should put it's name "sha256salted_encoder" and not acme.test.sha256salted_encoder. in addition

// Add a new User
$user = new User();
$user->setUsername = 'username';
$user->setSalt(uniqid(mt_rand())); // Unique salt for user

// Set encrypted password
$encoder = $this->container->get('security.encoder_factory')
  ->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);

first of all we will call the security encoder, then we will find

sha256salted_encoder

and the service will be useful.

All the best

Comments

-1

Basically, you should / must only use the bcrypt encoder to safely store password into your database.

here is why:

http://dustwell.com/how-to-handle-passwords-bcrypt.html

http://adambard.com/blog/3-wrong-ways-to-store-a-password/

To configure this encoder you should edit your security.yml file

security:
    encoders:
        Symfony\Component\Security\Core\User\UserInterface: bcrypt

This encoder is used inside the UserPasswordEncoder class which can be found here: Symfony\Component\Security\Core\Encoder

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.