I have a legacy system which contains md5 hashed passwords. I have tested these to be correct and they do not use a salt.
security.yml
security:
encoders:
Namespace\MyBundle\Entity\User:
algorithm: md5
providers:
entityUsers:
entity: { class: NamespaceBundle:User, property: username }
In my User entity I have implemented UserInterface and made sure the salt is set to the empty string.
But I get a bad credentials error when trying to authenticate.
I have tried switching security.yml to plaintext and entered the hash and the system works fine.
Surely md5 should just work?
I was having exactly the same problem and had to dig into the code to find out why.
You don't need to create a custom encoder.
By default, the MessageDigestPasswordEncoder
encoder (Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder
) in Symfony 2.5 - and possibly all Symfony 2 releases - calculates the MD5 hash of the raw password, with/without using a salt, as expected, and then re-hashes the MD5 a number of times (5000 times, by default, in Symfony 2.5). To make things that little bit more exciting, the encoder will also base64-encode the hash, by default. Both of those features were causing problems for me.
You can fix the problem(s) by disabling the re-hashing and/or disabling the base64 encoding, in security.yml
, thus:
security:
encoders:
Namespace\Of\Your\User:
algorithm: md5
encode_as_base64: false
iterations: 0
Hope that saves you some time.
Turns out that the md5 in symfony2 uses a salt by default. There may be an easier way, but I just created a custom md5 password encoder interface that ignores salt.
Register a service
namespace.project.md5password.encoder:
class: Namepspace\MyBundle\Services\CustomMd5PasswordEncoder
Create the encoder service
namespace Namespace\MyBundle\Services;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
class CustomMd5PasswordEncoder implements PasswordEncoderInterface
{
public function __construct() {
}
public function encodePassword($raw, $salt) {
return md5($raw);
}
public function isPasswordValid($encoded, $raw, $salt) {
return md5($raw) == $encoded;
}
}
Use the new service in security.yml
security:
encoders:
Namespace\MyBundle\Entity\User:
id: namespace.project.md5password.encoder
Hope this helps