Blowfish PBKDF2 Migration Guide
Introduction
Openfire 5.1.0 introduces PBKDF2-HMAC-SHA512 key derivation for Blowfish encryption, replacing the legacy SHA1 key derivation method. This security enhancement provides significantly improved protection for encrypted properties stored in the Openfire database.
This guide describes how to migrate existing Openfire installations from SHA1 to PBKDF2 key derivation for Blowfish-encrypted properties.
Topics that are covered in this document:
Security Improvement Overview
The migration from SHA1 to PBKDF2 key derivation improves security in three key ways:
- Slow Key Derivation Function: PBKDF2 uses 100,000 iterations, making brute-force attacks computationally expensive and impractical.
- Random Salt: Each Openfire installation uses a unique random salt (32 bytes), preventing rainbow table attacks and ensuring that identical passwords produce different derived keys across installations.
- Industry Standard Algorithm: PBKDF2-HMAC-SHA512 is a well-vetted algorithm recommended by NIST and other security standards organisations.
What Properties Are Affected: This migration applies to all properties encrypted with Blowfish encryption, including database passwords, LDAP bind passwords, and any custom encrypted properties. Properties encrypted with AES are not affected by this migration.
Who Needs to Migrate
New Installations (Openfire 5.1.0+)
Action Required: None. New installations automatically use PBKDF2.
When you complete the setup wizard in Openfire 5.1.0 or later, PBKDF2 key derivation
is automatically enabled. You can verify this by accessing the migration page directly
at https://your-server:9090/security-blowfish-migration.jsp, which will
show "Your installation is already using PBKDF2-HMAC-SHA512".
Existing Installations Using Blowfish Encryption
Action Required: Migration recommended for improved security.
If you upgraded from a previous version of Openfire and use Blowfish encryption (the default), your installation continues to use SHA1 key derivation for backward compatibility. You should migrate to PBKDF2 to benefit from the security improvements.
To check if migration is needed, log into the admin console. If migration is needed,
a warning banner will appear on the Server Information page (the homepage) with a link
to the migration tool. Alternatively, navigate directly to
https://your-server:9090/security-blowfish-migration.jsp.
Existing Installations Using AES Encryption
Action Required: None. This migration does not apply to AES encryption.
If your installation uses AES encryption (configured in conf/security.xml),
this migration is not applicable. The migration tool will indicate that your server
uses AES encryption and no action is required.
Single-Node Migration Procedure
This procedure applies to standalone Openfire installations (non-clustered). The migration runs while the server continues accepting connections. Users remain connected and can continue messaging throughout the process. The migration is typically fast (under 10 seconds for most installations) and does not interrupt service.
Prerequisites
Before beginning the migration, ensure you have:
- Administrative access to the Openfire admin console
- Ability to backup the Openfire database
- Access to the server filesystem to backup
conf/security.xmlandconf/openfire.xml
Migration Steps
-
Backup the Database
Create a complete backup of your Openfire database. The migration is wrapped in a database transaction and will roll back on failure, but having a backup provides an additional safety mechanism.
Example backup commands:
- PostgreSQL:
pg_dump openfire > openfire_backup.sql - MySQL:
mysqldump openfire > openfire_backup.sql - Embedded HSQLDB:
cp -r embedded-db/ embedded-db.backup/
Note: Replace "openfire" with your actual database name if different. Check the
<database>element inconf/openfire.xmlto confirm your database name. - PostgreSQL:
-
Backup security.xml and openfire.xml
Create backups of the configuration files:
cp /opt/openfire/conf/security.xml /opt/openfire/conf/security.xml.backup cp /opt/openfire/conf/openfire.xml /opt/openfire/conf/openfire.xml.backup
(Adjust the path if Openfire is installed in a different location)
-
Access the Migration Page
Log into the Openfire admin console. If migration is needed, a warning banner will appear on the Server Information page (the homepage) with a link to the migration tool. Click the link, or navigate directly to
https://your-server:9090/security-blowfish-migration.jsp.The page will display the current encryption status, including the key derivation function in use and the number of encrypted properties that will be migrated.
-
Confirm Backups
Check all three confirmation boxes on the migration page:
- "I have backed up the Openfire database"
- "I have backed up the conf/security.xml file"
- "I have backed up the conf/openfire.xml file"
-
Run the Migration
Click the "Migrate to PBKDF2" button. You will be prompted to confirm the operation. Click "OK" to proceed.
The migration process will:
- Decrypt all encrypted properties using the SHA1-derived key
- Re-encrypt all properties using the PBKDF2-derived key
- Update all encrypted values in the database
- Update
conf/security.xmlto use PBKDF2
The migration typically completes in under 10 seconds for installations with fewer than 100 encrypted properties.
-
Verify Success
After successful migration, you will see a success message indicating how many properties were migrated. The migration page will now show "Your installation is using PBKDF2-HMAC-SHA512 key derivation".
Verify that Openfire continues to function normally:
- Test database connectivity (indicates database password still decrypts correctly)
- Test LDAP connections if configured
- Check that users can authenticate
- Review
logs/openfire.logfor any errors
You can also verify the updated
conf/security.xmlcontains a<blowfish>element (inside the<encrypt>section) with the following structure:<encrypt> ... <blowfish> <kdf>pbkdf2</kdf> <salt>BASE64_ENCODED_SALT</salt> </blowfish> </encrypt>
Rollback Procedure (Single-Node)
If you encounter issues after migration and need to rollback:
-
Stop Openfire
systemctl stop openfire
Or use the appropriate stop command for your installation method.
-
Restore the Database
Restore your database backup:
- PostgreSQL:
psql openfire < openfire_backup.sql - MySQL:
mysql openfire < openfire_backup.sql - Embedded HSQLDB:
rm -rf embedded-db/ && cp -r embedded-db.backup/ embedded-db/
- PostgreSQL:
-
Restore security.xml and openfire.xml
cp /opt/openfire/conf/security.xml.backup /opt/openfire/conf/security.xml cp /opt/openfire/conf/openfire.xml.backup /opt/openfire/conf/openfire.xml
-
Start Openfire
systemctl start openfire
-
Verify Rollback
Verify that Openfire starts successfully and encrypted properties decrypt correctly. The system is now back to using SHA1 key derivation (pre-migration state).
Clustered Migration Procedure
This procedure applies to Openfire installations with multiple nodes in a cluster. Important: Clustered migration requires a maintenance window as all nodes must be offline during the migration except for the one node performing the migration.
Why Cluster Migration Requires Downtime
In a clustered environment:
- The database is shared across all nodes (stores encrypted property values)
- The security.xml file is local to each node (stores KDF configuration and salt)
Migration updates both the database (re-encrypted property values) and security.xml
(KDF setting). If multiple nodes are running with mismatched configurations, nodes using SHA1
will be unable to decrypt properties that were re-encrypted with PBKDF2, causing failures
across the cluster.
Critical: You cannot have nodes with different KDF settings accessing the same database simultaneously. This is why all nodes except the migration node must be offline during the migration process.
Prerequisites
Before beginning the migration, ensure you have:
- Administrative access to all cluster nodes
- Ability to stop and start all cluster nodes
- Ability to backup the shared database
- SSH or filesystem access to all nodes to backup and sync
security.xmlandopenfire.xml - A scheduled maintenance window (15-30 minutes recommended)
Migration Steps
Phase 1: Upgrade All Nodes (Optional - Can Use Rolling Upgrade)
If you are upgrading from a version prior to Openfire 5.1.0, you can perform a rolling upgrade first:
- Upgrade Node 1 to Openfire 5.1.0, restart, verify it joins cluster
- Upgrade Node 2 to Openfire 5.1.0, restart, verify it joins cluster
- Upgrade Node 3 to Openfire 5.1.0, restart, verify it joins cluster
At this point, all nodes are running Openfire 5.1.0 but still using SHA1 key derivation (backward compatible). The cluster operates normally. Migration is performed separately during a maintenance window.
Phase 2: Plan and Schedule Maintenance Window
- Schedule a maintenance window (15-30 minutes recommended)
- Notify users of the planned downtime
- Prepare backup procedures and rollback plan
- Choose one node to perform the migration (typically Node 1)
Phase 3: Execute Migration (During Maintenance Window)
-
Stop All Cluster Nodes Except One
Stop all nodes except the one you'll use for migration (e.g., Node 1):
systemctl stop openfire # On Node 2 systemctl stop openfire # On Node 3 # etc. for all other nodes
Verify: Check the admin console on Node 1 shows cluster size = 1, or check logs confirm other nodes have disconnected.
-
Stop the Migration Node
Stop the remaining node:
systemctl stop openfire # On Node 1
All cluster nodes are now offline.
-
Backup Everything
Create backups whilst all nodes are offline:
Backup the shared database:
- PostgreSQL:
pg_dump openfire > openfire_backup.sql - MySQL:
mysqldump openfire > openfire_backup.sql
Backup
security.xmlandopenfire.xmlon all nodes:ssh node1 "cp /opt/openfire/conf/security.xml /opt/openfire/conf/security.xml.backup" ssh node1 "cp /opt/openfire/conf/openfire.xml /opt/openfire/conf/openfire.xml.backup" ssh node2 "cp /opt/openfire/conf/security.xml /opt/openfire/conf/security.xml.backup" ssh node2 "cp /opt/openfire/conf/openfire.xml /opt/openfire/conf/openfire.xml.backup" ssh node3 "cp /opt/openfire/conf/security.xml /opt/openfire/conf/security.xml.backup" ssh node3 "cp /opt/openfire/conf/openfire.xml /opt/openfire/conf/openfire.xml.backup"
- PostgreSQL:
-
Start Migration Node Only
Start only Node 1 (all other nodes remain stopped):
systemctl start openfire # On Node 1 only
Wait for Node 1 to fully start. Monitor logs or wait until admin console is accessible.
Verify: Cluster size should be 1 (only this node).
-
Run Migration via Admin Console
On Node 1, access the admin console. A warning banner will appear on the Server Information page (the homepage) with a link to the migration tool. Click the link, or navigate directly to
https://your-server:9090/security-blowfish-migration.jsp.Check all three confirmation boxes:
- "I have backed up the Openfire database"
- "I have backed up the conf/security.xml file"
- "I have backed up the conf/openfire.xml file"
Click "Migrate to PBKDF2" and confirm.
The migration will decrypt all properties (using SHA1), re-encrypt them (using PBKDF2), update the database, and update Node 1's
security.xml.Wait for the success message: "Successfully migrated N properties from SHA1 to PBKDF2".
-
Verify Migration on Node 1
Check that Node 1's
security.xmlwas updated:ssh node1 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml"
You should see:
<blowfish> <kdf>pbkdf2</kdf> <salt>BASE64_ENCODED_SALT</salt> </blowfish>
Important: Note the exact salt value. All nodes must have the same salt.
-
Stop Migration Node
Stop Node 1 cleanly:
systemctl stop openfire # On Node 1
All nodes are now offline again.
-
Sync security.xml to All Other Nodes
Copy the updated
security.xmlfrom Node 1 to all other nodes. You can either copy the entire file or manually edit each node's file.Option A - Copy Entire File (Recommended):
scp node1:/opt/openfire/conf/security.xml node2:/opt/openfire/conf/security.xml scp node1:/opt/openfire/conf/security.xml node3:/opt/openfire/conf/security.xml
Option B - Manual Edit Each Node:
On each node (Node 2, Node 3, etc.), edit
/opt/openfire/conf/security.xml:- Change
<kdf>sha1</kdf>to<kdf>pbkdf2</kdf> - Add the
<salt>element with the exact Base64 value from Node 1
Critical: All nodes must have identical KDF and salt values.
- Change
-
Sync openfire.xml to Other Nodes (If Applicable)
If your
openfire.xmlcontains encrypted properties (check yoursecurity.xmlfor<property><name>elements that reference properties stored in openfire.xml), these values were also re-encrypted during migration and must be synced to other nodes.Option A - Copy Entire File:
If all nodes have identical
openfire.xmlconfigurations (same ports, same network interfaces, same settings):scp node1:/opt/openfire/conf/openfire.xml node2:/opt/openfire/conf/openfire.xml scp node1:/opt/openfire/conf/openfire.xml node3:/opt/openfire/conf/openfire.xml
Option B - Manual Sync:
If nodes have different configurations (different ports, network interfaces, etc.), manually compare the files and copy only the encrypted property values from Node 1 to the other nodes, preserving node-specific settings.
Note: If your
openfire.xmldoes not contain any encrypted properties, you can skip this step. -
Verify All Nodes Have Matching Configuration
Compare
security.xmlon all nodes:ssh node1 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml" ssh node2 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml" ssh node3 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml"
All should show
pbkdf2and the same salt value. -
Start All Cluster Nodes
Start nodes one at a time, verifying each joins the cluster successfully:
systemctl start openfire # On Node 1 # Wait 30-60 seconds, verify Node 1 started successfully systemctl start openfire # On Node 2 # Wait 30-60 seconds, verify Node 2 joined cluster systemctl start openfire # On Node 3 # Wait 30-60 seconds, verify Node 3 joined cluster
Check the admin console or logs to verify cluster size returns to expected count.
-
Verify Cluster Health Post-Migration
Perform comprehensive verification:
- Admin console shows all nodes in cluster
- Test encrypted property access on each node (e.g., database connection works)
- Create a test encrypted property, verify it replicates across nodes
- Check
logs/openfire.logon all nodes for any decryption errors - Monitor cluster for 15-30 minutes to ensure stability
-
End of Maintenance Window
Once cluster health is verified, notify users that the service is back online.
Critical Errors to Avoid (Clustered Environments)
DO NOT run migration with other nodes still active:
- Problem: Node 1 migrates database to PBKDF2, but Node 2 (still running) tries to decrypt with SHA1.
- Result: Node 2 cannot decrypt properties, cluster breaks, service disruption.
DO NOT start other nodes before syncing security.xml:
-
Problem: Node 1 has
kdf=pbkdf2, but Node 2 still haskdf=sha1(not updated). - Result: Node 2 derives wrong key, cannot decrypt properties, node fails to start or operate correctly.
DO NOT allow salt mismatch between nodes:
-
Problem: Node 1 has
salt=abc123..., but Node 2 hassalt=xyz789...(different values). - Result: Different derived keys per node, Node 2 cannot decrypt, cluster inconsistency.
DO NOT forget to sync openfire.xml if it contains encrypted properties:
-
Problem: Node 1's
openfire.xmlhas re-encrypted values, but Node 2'sopenfire.xmlstill has SHA1-encrypted values. - Result: Node 2 cannot decrypt XML-stored properties, configuration errors on startup.
CORRECT PROCEDURE: All nodes stopped → migrate on one node → sync security.xml and openfire.xml (if applicable) to all nodes → start all nodes.
Rollback Procedure (Clustered)
If you encounter issues after migration and need to rollback:
-
Stop All Cluster Nodes Immediately
systemctl stop openfire # On all nodes
-
Restore Shared Database
Restore the database backup:
- PostgreSQL:
psql openfire < openfire_backup.sql - MySQL:
mysql openfire < openfire_backup.sql
- PostgreSQL:
-
Restore security.xml and openfire.xml on All Nodes
ssh node1 "cp /opt/openfire/conf/security.xml.backup /opt/openfire/conf/security.xml" ssh node1 "cp /opt/openfire/conf/openfire.xml.backup /opt/openfire/conf/openfire.xml" ssh node2 "cp /opt/openfire/conf/security.xml.backup /opt/openfire/conf/security.xml" ssh node2 "cp /opt/openfire/conf/openfire.xml.backup /opt/openfire/conf/openfire.xml" ssh node3 "cp /opt/openfire/conf/security.xml.backup /opt/openfire/conf/security.xml" ssh node3 "cp /opt/openfire/conf/openfire.xml.backup /opt/openfire/conf/openfire.xml"
-
Verify All Nodes Have KDF=sha1 (Pre-Migration State)
ssh node1 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml" ssh node2 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml" ssh node3 "grep -A2 '<blowfish>' /opt/openfire/conf/security.xml"
All should show
sha1or have no KDF element (defaults to sha1). -
Start All Nodes
systemctl start openfire # On all nodes
-
Verify Cluster Health
Verify all nodes join the cluster and encrypted properties decrypt correctly. The cluster is now back to using SHA1 key derivation (pre-migration state).
Troubleshooting
"Migration failed: Transaction rolled back" Error
Symptom: Migration fails midway through with an error indicating the database transaction was rolled back.
Cause: One or more encrypted properties failed to decrypt or re-encrypt. Possible causes include:
- Corrupted encrypted property value in database
- Database connection issue during migration
- Mismatched encryption key
Solution:
-
Check
logs/openfire.logfor specific property names that failed. The log will indicate which property caused the failure. - If the issue is a corrupted property, you may need to delete or manually repair that property before retrying migration.
-
Verify your master encryption key in
security.xmlis correct. If the key was changed, properties encrypted with the old key cannot be decrypted. - If the issue persists, restore from backup and report the issue in the Openfire category on the Ignite Realtime community forum with the error logs.
Important: The database transaction rollback means no changes were committed. Your installation remains in the pre-migration state (SHA1) and can continue operating normally. You can investigate the issue and retry migration when resolved.
Node Fails to Start After Cluster Migration
Symptom: After completing cluster migration, one or more nodes fail to start or fail to decrypt properties.
Cause: The node's security.xml was not synced correctly,
resulting in KDF or salt mismatch.
Solution:
-
Stop the failing node:
systemctl stop openfire
-
Copy the updated
security.xmlfrom the migration node:scp working-node:/opt/openfire/conf/security.xml /opt/openfire/conf/security.xml
-
Verify the
<blowfish>section matches the working node exactly, including KDF and salt values. -
Restart the node:
systemctl start openfire
- Check logs to verify the node starts successfully and joins the cluster.
Properties Cannot Decrypt After Migration
Symptom: After migration, Openfire fails to decrypt properties. Database connection fails, LDAP connection fails, or other encrypted properties are inaccessible.
Cause: Mismatch between database state and security.xml:
-
Database contains PBKDF2-encrypted values, but
security.xmlstill haskdf=sha1(security.xml not updated). -
Database contains SHA1-encrypted values, but
security.xmlhaskdf=pbkdf2(database not updated, but security.xml was).
Solution:
If database was not updated, but security.xml was changed:
- Stop Openfire
- Restore
security.xmlandopenfire.xmlfrom backups (restores SHA1 setting) - Start Openfire - properties should decrypt correctly
- Retry migration carefully, ensuring migration completes successfully
If database was updated, but security.xml was not:
- Stop Openfire
- Manually update
security.xmlto use<kdf>pbkdf2</kdf> - Ensure the
<salt>element exists (salt should have been generated during migration) - Start Openfire - properties should decrypt correctly
If you cannot resolve the issue:
- Stop Openfire
- Restore database,
security.xml, andopenfire.xmlfrom backups - Start Openfire - system returns to pre-migration state
- Report the issue in the Openfire category on the Ignite Realtime community forum with error logs before retrying migration
Getting Help
If you encounter issues not covered in this troubleshooting guide, please seek assistance:
- Community Forum: https://discourse.igniterealtime.org
When seeking help, please include:
- Openfire version number
- How was Openfire installed (RPM, deb, tar.gz, exe, etc.)
- Database type (PostgreSQL, MySQL, etc.)
- Single-node or clustered deployment
- Are you using any custom plugins or authentication methods?
- Relevant excerpts from
logs/openfire.log - Contents of the
<blowfish>section insecurity.xml(safe to share)