Upgrading user passwords from salted SHA1 to bcrypt - php

I've been hired to rebuild a actively used application that was built on CodeIgniter 1.7.3 (on a PHP 4.2 server) using Laravel 4 on a new PHP 5.3 server.
The system has about ~500 users whose passwords are encrypted with a salted SHA-1 hash. I'd like to use bcrypt to increase the application's security as well as to integrate with Laravel 4's authentication system.
How would you suggest migrating these users passwords?

The whole point of a hash is that you can't recover the original password.
You have three options:
Store bcrypt hashes of the SHA1 hashes, then SHA1 hash each password before bcrypting it on every login.
This may not be a good idea.
Upgrade each hash next time that user logs in. (so that you have the plain text to hash)
This is the best option, but you need to keep your SHA1 hashes and transition code until every single user logs in
Reset every user to a random bcrypted password and force them all to use Forgot Password to change it back.
You probably don't want to do this

Add a column to your database that tells the system which hashing algorithm has been used
On login, check the credentials as normal
If they're using the old one and login is successful - bcrypt the password they entered and update their password and algorithm in the database.

You could create a random password for each user and send out a notification email to everyone with their new password. But this will result in confusion if a user doesn't see the email.
I recommend that you add another db field for the bcrypt value and then create an entry when a user logs in for the first time after the change. You can use either a separate field or delete the old hash to keep track.
When your active users have migrated, feel free to use the random password approach for the rest of your userbase to finish the migration.

Related

migrating b-crypt hashed passwords from Ruby on Rails to Wordpress

I have an application with user table and hashed passwords created by Devise in a RubyonRails website.
I want to migrate those users to Wordpress.
According to PHP documentation you can use the BCRYPT algorithm for passwords, and this is the same encryption method (afaik) that is used by Devise.
The hashed passwords I have are all 60 characters long, and they all begin with the prefix $2y$
However, when I try to follow the code example
<?php
echo "Welcome to PHPSandbox";
$hash = '$2y${MyHASHEDPASSWORDHERE}';
password_verify('{MYPASSWORDHERE}', $hash)
It outputs false
Yet when I follow the example on the documentationit outputs true.
Devise must have added some extra complexity to the Hash Password and so now when I run password_verify using PHP 8 it is not able to verify that the hash and the password match.
How can I verify the hashed passwords coming from Devise on Ruby on Rails application in PHP?
Migration of password can be integrated into the application while still on the old system.
You would need to have the old password hashing mechanism in place, and the new algorithm plus a second column in your database to store the password with the new hashing method.
When the user authenticates, eg. the first password check validates the password, you can hash it with the second method into the second column (you'd only do this, if the second column is empty yet)
At some point, you remove the old password hash & database column. Anybody who hasn't authenticated until then must go through the "password forgotten" process.

Password Migration - Drupal SHA2 to PHP MD5 Version

As everyone know that Drupal store password using SHA2 method which involves Encryption + Hashing + Salt on it.
I have a list of passwords which are currently used by some of my clients in Drupal. Since we have migrated the whole system to Custom PHP therefore we are unable to use the same passwords. And we really don't want to ask everyone in the database to generate a new passwords.
If there is any way, where we could change all the passwords which are in SHA2 (Drupal - 512 Encryption) to support our new system which is currently having MD5/SHA1 (PHP Mysql database).
Any help would be appreciated.
You really do not want to go to MD5. It's dead as far as a password hashing method goes. You should be moving to password_hash and something like Bcrypt at the absolute minimum.
Remember, when someone logs in and you verify their password is correct that's your chance to update how the password is hashed in the database. If they're using a weak method, switch to a strong one and save their user record. Nobody will know what you've done.
After a year or so you can always force-expire all the old-format passwords if you're concerned about that lingering liability. All of your active users will be unaffected.
I wouldn't suggest changing to another password format and especially not MD5. Since you already have the passwords you can implement the Drupal password hashing in your own application and just continue using the existing passwords.
More information about the password formats can be found for example in this question.
I think you should use a 'transition'. For example use your new system but let the old password in the database.
In your code, on user login you get the password (ex: $_POST['pwd']), and crypt it using a strong algorithm (not MD5). Then, you can insert it in a new field of your database.
So, your new database could have a field 'old_pwd' that contains the old password and a field 'pwd' that contains the new password using your new algorithm. According to me this is the easiest to do this migration.
Password checking code is pretty similar in Drupal 7 and 8 and easy to borrow, it does not have any strong dependency on Drupal component. It should be pretty easy to add support for Drupal's hashes to your password checking code. Allowing use to authenticate using their password by storing Drupal's hashes in your database.
To migrate to your new hashing algorithm, simply re-hash passwords on successful authentication. This way, old hashes will be replaced over time.
Drupal has a similar mechanism to ensure transparent updates or old MD5 hashes. Look at the user_check_password() and user_needs_new_hash() to see how it could be done.

How to update stored passwords from SHA1 to password_hash

I am kind of new to PHP and MySQL. I have a list of 200 passwords stored in MySQL using SHA1. I would to update these to password_hash(). What is the best way to do this?
You can't do this directly as the SHA1 hash is not reversible. You can only calculate the password_hash when the user logs in succesfully.
You cannot generate the new hash without having the plaintext.
What I would do in this situation would be to force all of the users to reset their passwords after the new hashing algo is in place. If you already have a password reset system this should be fairly easy. If not you'll have to build one.
This is how I see it working
You discard all of the sha1 passwords as soon as the new system is ready. Immediately.
When a user tries to login, if they do not have a password hashed with the new algo, send them a password reset email.
The reset email will contain a link with a unique ID that will allow the user to create a new password
You could slowly migrate to the new system by updating user's password to the new hash as they login, but you would still be storing the weaker hash until a user logs in. I think it is better to just discard the old system and start fresh rather than trying to juggle the old and new hashes.
The hash mechanism used by password_hash is one-way which means that there is no way to get the actual value from the hash. I will make two assumptions here:
You want to convert from SHA-1 to password_hash default.
You have users logging in regularly.
Create an extra column in your password table for storing the new hash. When a user logs in successfully, hash the password using the default hash and store it in the new column. After a certain period of time, you will have most of the hashes converted. Flag the remaining users and ask them to reset their passwords. Obviously, your password checking mechanism will have to be modified to check the password using the default value first. If the value of the hash is empty, then you will have to proceed with the SHA-1 hash (and its "conversion").
In a real world scenario, this will be a better solution for your customers than asking all the customers to reset their passwords.

How to transfer wordpress mysql md5 user passwords field into another mysql table

I have a WP website and another website with similar service. I want to duplicate db user password and email fields into new mysql database.
$A$B6NS8Cv837YVS1c/JKLE1 - WP password (example)
83703ccdb3cb2dad97f76f986400b43f87b989ce - Another website MD5 password (example)
And the question is how I can transfer WP user's passwords to a new mysql table so they can work?
Thanks
You will copy the md5 password into your new system.
Then you can have a login screen which does the exact same hashing on the entered password and compares the two.
Encryption is one way so you will never know the password but you certainly will be able to use it in another system.
As someone mentioned in the comments you will need to know exactly how WordPress hashes the password but this should all be in the source code.
However if you have other users already in the system that use a different hashing system you will need to flag them to decide what hashing to do.
When they do decide to change their password or via recommendation, you can migrate them to the other hashing system.
You can't - it's rather the point of hashing passwords that you can't undo it. You could potentially use a rainbow table to try and crack the MD5 hashes and get the original password before re-hashing it the way Wordpress does it, but if your users' passwords are vulnerable to such an attack, you should probably be concerned for their account security!
Personally, I would announce to the users that a big merge is happening, and for safety reasons they must change their password. A lot of people will probably just "change" it to the same thing, and that's fine, because internally you're just rehashing the password and can then delete the old, unsafe MD5 hash.

Pitfalls of encrypting (with salt) of a md5-hashed-password (php)

A client has a huge userbase and I'm required to encrypt/hash passwords in a secure manner. The problem is I can't ask every user to change their password and the passwords are already hashed with md5() without a salt. One way of doing this is to encrypt the current passwords with a salt and when a user changes or resets the password i just encrypt it with the salt.
Are there any pitfalls or more or less obvious dangers of doing so [ i mean sha1(md5(password) with salt) ]?
Thank you for your time
Add a new field to the user table for storing the new securely hashed passwords - for this, please do something safe involving per-user salt and multiple rounds. Check what other people are doing (ie., bcrypt) instead of rolling your own.
When doing a password check, if the newPass field is null, use the old password lookup, but urge users to do a password reset once authenticated.
Modifying the current (old) password scheme to be hash(perUserSalt + existingPassWordHash) should work fine.
if you plan to use sha1(md5(password).$salt) it's all right.
You can use this system even further. No need to take any special action when user changes a password. Just encrypt it the same way: sha1(md5(new password).$salt)
It depends on what attack you are attempting to defend against. If the attack is someone viewing the database, then you could use a symmetric encryption method (like AES) with a key defined outside the database. Using this method requires the authentication procedure know the encryption key and you update all the rows in the database by encrypting the hashed password with the encryption key.
If the above is not an option, you have a problem. ;) The problem is that right now you don't know what any user's password actually is. All you have is the hashed version. Your routine for verifying a login is to take the input supplied by the user, hash it, and compare the computed hash with the stored hash.
Your option would be to store the old hash and create a new field to store the new algorithm. Then as people log into the system, perform the upgraded salted-hash and delete the old hash. This will work as you expect, but if a person never logs back in (or changes their password) they will never upgrade to the salted version of the hash.
My personal opinion is to use the AES encrypted option since that prevents the casual viewing of hashed passwords and it covers all the passwords in the database.

Categories