Password Migration in Drupal 9 from Drupal 7, WordPress, and Custom CMS
Password migration is basically part of website migration. We can migrate content, images, documents, categories, and other content very easily because these are almost straightforward. In migration, We pick the content from the source and put it into a destination which is called the lift-and-shift approach. In Drupal 9, Password migration is a bit tricky due to the different encryption algorithms used in each application.
In this article, I am going to describe how you can migrate the following types of passwords into Drupal 8, Drupal 9, and Drupal 10+:
- MD5 Hash Algorithm
- Portable Phpass Hashes
- Custom Password Algorithm
- Plain Password Migration
Prerequisites: You should have knowledge of Drupal migration.
MD5 Hash Algorithm:
MD5 Password Algorithm used in Drupal 5, Drupal 6, Drupal 7, osCommerce, SuiteCRM, miniBB, SugarCRM and etc.
MD5 password hashes must be migrated to Drupal 8+ using the md5_passwords: true configuration option so that the users can use their old passwords. The passwords are salted and re-hashed before they are saved into the Drupal 8+ database. The identifier of md5 migrated password id U$. When the user logs in to your Drupal site for the first time, Drupal will re-hash the password.
Create a custom module custom_migrate inside modules/custom/ folder with all the basic required files.
1. Migration Group configuration file: web/modules/custom/custom_migrate/config/install/migrate_plus.migration_group.md5hash.yml
2. Migration configuration files: web/modules/custom/custom_migrate/config/install/migrate_plus.migration.md5_hash.yml
Portable Phpass hashes:
phpass (pronounced “pH pass”) is a portable public domain password hashing framework for use in PHP applications. Phpass has been integrated into WordPress 2.5+ 2, bbPress 3, Vanilla 4, phpBB3 8, and Joomla starting with versions 2.5.18 and 3.2.1.
The password hashes generated with Phpass look like this: $P$B4J4RkvSe3QowfF/v6oHionn8CyW.a. The $P$ is the so-called hash type identifier which indicates that the hash is a portable Phpass hash. The string after that consists of salt and a hash. The portable Phpass hashes can be migrated to Drupal 8 as-is. When the user logs in to your Drupal 8 site for the first time, Drupal will re-hash the password.
1. Migration Group configuration file: web/modules/custom/custom_migrate/config/install/migrate_plus.migration_group.portable_phpass.yml
2. Migration configuration files: web/modules/custom/custom_migrate/config/install/migrate_plus.migration.portable_phpass.yml
Custom Password algorithm:
If the source system passwords are hashed with some other algorithm, it is possible to add support for these hashes by extending the Drupal core password service. When the user tries to log in, the password hash checking is done in PhpassHashedPassword::check(). As you can see, there is handling for different hash types, which are identified by hash type identifiers such as U$, $S$, $P$, and $H$. You can add handling for your legacy hashes, provided that you know the algorithm that was used to generate the hashes in your source system. You will need to prefix the old hashes with a special hash type identifier.
1. Migration Group configuration file: web/modules/custom/custom_migrate/config/install/migrate_plus.migration_group.custom_hash.yml
2. Migration configuration files: web/modules/custom/custom_migrate/config/install/migrate_plus.migration.sha512_hash.yml
3. Migration source plugin file web/modules/custom/custom_migrate/src/Plugin/migrate/source/Sha512Hash.php
4. Override the service file web/modules/custom/custom_migrate/custom_migrate.services.yml
5. Create a class file in web/modules/custom/custom_migrate/src/Services/CustomMigratePasswordService.php
Plain Password Migration:
If the passwords are plain text in the source, you can preserve the passwords by processing them through md5 during the migration using the Callback process plugin and then using the md5_passwords: true configuration option in the yml file, same as the MD5 Password Algorithm.