Openfire Logo

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:

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.xml and conf/openfire.xml

Migration Steps

  1. 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 in conf/openfire.xml to confirm your database name.

  2. 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)

  3. 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.

  4. 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"
  5. 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.xml to use PBKDF2

    The migration typically completes in under 10 seconds for installations with fewer than 100 encrypted properties.

  6. 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.log for any errors

    You can also verify the updated conf/security.xml contains 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:

  1. Stop Openfire
    systemctl stop openfire

    Or use the appropriate stop command for your installation method.

  2. 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/
  3. 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
  4. Start Openfire
    systemctl start openfire
  5. 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.xml and openfire.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:

  1. Upgrade Node 1 to Openfire 5.1.0, restart, verify it joins cluster
  2. Upgrade Node 2 to Openfire 5.1.0, restart, verify it joins cluster
  3. 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

  1. Schedule a maintenance window (15-30 minutes recommended)
  2. Notify users of the planned downtime
  3. Prepare backup procedures and rollback plan
  4. Choose one node to perform the migration (typically Node 1)

Phase 3: Execute Migration (During Maintenance Window)

  1. 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.

  2. Stop the Migration Node

    Stop the remaining node:

    systemctl stop openfire  # On Node 1

    All cluster nodes are now offline.

  3. 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.xml and openfire.xml on 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"
  4. 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).

  5. 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".

  6. Verify Migration on Node 1

    Check that Node 1's security.xml was 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.

  7. Stop Migration Node

    Stop Node 1 cleanly:

    systemctl stop openfire  # On Node 1

    All nodes are now offline again.

  8. Sync security.xml to All Other Nodes

    Copy the updated security.xml from 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.

  9. Sync openfire.xml to Other Nodes (If Applicable)

    If your openfire.xml contains encrypted properties (check your security.xml for <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.xml configurations (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.xml does not contain any encrypted properties, you can skip this step.

  10. Verify All Nodes Have Matching Configuration

    Compare security.xml on 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 pbkdf2 and the same salt value.

  11. 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.

  12. 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.log on all nodes for any decryption errors
    • Monitor cluster for 15-30 minutes to ensure stability
  13. 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 has kdf=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 has salt=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.xml has re-encrypted values, but Node 2's openfire.xml still 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:

  1. Stop All Cluster Nodes Immediately
    systemctl stop openfire  # On all nodes
  2. Restore Shared Database

    Restore the database backup:

    • PostgreSQL: psql openfire < openfire_backup.sql
    • MySQL: mysql openfire < openfire_backup.sql
  3. 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"
  4. 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 sha1 or have no KDF element (defaults to sha1).

  5. Start All Nodes
    systemctl start openfire  # On all nodes
  6. 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:

  1. Check logs/openfire.log for specific property names that failed. The log will indicate which property caused the failure.
  2. If the issue is a corrupted property, you may need to delete or manually repair that property before retrying migration.
  3. Verify your master encryption key in security.xml is correct. If the key was changed, properties encrypted with the old key cannot be decrypted.
  4. 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:

  1. Stop the failing node:
    systemctl stop openfire
  2. Copy the updated security.xml from the migration node:
    scp working-node:/opt/openfire/conf/security.xml /opt/openfire/conf/security.xml
  3. Verify the <blowfish> section matches the working node exactly, including KDF and salt values.
  4. Restart the node:
    systemctl start openfire
  5. 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.xml still has kdf=sha1 (security.xml not updated).
  • Database contains SHA1-encrypted values, but security.xml has kdf=pbkdf2 (database not updated, but security.xml was).

Solution:

If database was not updated, but security.xml was changed:

  1. Stop Openfire
  2. Restore security.xml and openfire.xml from backups (restores SHA1 setting)
  3. Start Openfire - properties should decrypt correctly
  4. Retry migration carefully, ensuring migration completes successfully

If database was updated, but security.xml was not:

  1. Stop Openfire
  2. Manually update security.xml to use <kdf>pbkdf2</kdf>
  3. Ensure the <salt> element exists (salt should have been generated during migration)
  4. Start Openfire - properties should decrypt correctly

If you cannot resolve the issue:

  1. Stop Openfire
  2. Restore database, security.xml, and openfire.xml from backups
  3. Start Openfire - system returns to pre-migration state
  4. 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:

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 in security.xml (safe to share)