Openfire: Property Encryption Guide

# Property Encryption Guide

## Introduction

This guide describes how Openfire encrypts sensitive configuration properties to protect credentials such as database passwords, LDAP bind passwords, and API keys. Openfire automatically encrypts these values to prevent unauthorised access when configuration files are viewed or backed up.

Topics covered in this document:

## Quick Reference: XML vs Database Property Encryption

Openfire stores encrypted properties in two locations with different encryption implementations. This table summarises the key differences:

Feature | XML Properties | Database Properties
--- | --- | ---
Storage location | `conf/openfire.xml` | `ofProperty` table
Random IV support | Openfire 5.1+ | Supported for several major versions
Auto-upgrade applies | Yes | No (not needed)
IV storage | XML attribute | Database column

## Encryption Overview

Openfire protects sensitive configuration values using AES encryption. This prevents passwords and other credentials from being readable in configuration files and database backups.

### Security Improvements in Openfire 5.1

Openfire 5.1 included significant security improvements to XML property encryption (properties stored in `openfire.xml`):

- Random initialisation vectors – XML properties now use unique random IVs, preventing pattern analysis attacks where identical plaintext produces identical ciphertext. (Database properties have used random IVs for several major versions.)
- Automatic upgrades – Legacy encrypted XML properties are automatically upgraded to use stronger encryption when accessed
- Backward compatibility – Existing installations work without manual intervention

## Property Storage Locations

Openfire stores properties in two different locations, and encryption works for both:

### Configuration File (`openfire.xml`)

Contains bootstrap properties needed before the database is available, such as database connection settings and server domain. These properties are specific to each server instance and stored in `conf/openfire.xml`.

Common encrypted properties in `openfire.xml`:

- Database password (`database.defaultProvider.password`)
- LDAP bind password (`ldap.adminPassword`)

### Database (`ofProperty` table)

Contains runtime properties that are shared across all servers in a clustered deployment. Most properties set via the admin console are stored here.

Common encrypted properties in the database:

- Email server passwords (`mail.smtp.password`)
- Plugin settings and API keys
- Integration credentials configured via admin console

## How Property Encryption Works

### Encryption Process

When a property is marked for encryption, Openfire automatically encrypts its value before saving it to the configuration file or database. The encrypted value is stored with additional metadata that allows Openfire to decrypt it when needed.

Example of an encrypted property in `openfire.xml`:

    <database>
        <password encrypted="true" iv="MTIzNDU2Nzg5MDEyMzQ1Ng==">
            EncryptedPasswordValueHere
        </password>
    </database>

The `encrypted="true"` attribute indicates the value is encrypted. The `iv` attribute contains the initialisation vector used for encryption (Base64-encoded).

### Database Storage Format

For properties stored in the database, the encrypted value and IV are stored in separate columns of the `ofProperty` table:

- `propValue` – The encrypted value (Base64-encoded)
- `encrypted` – Boolean flag indicating encryption
- `iv` – The initialisation vector (Base64-encoded)

Database properties have used random IVs for several major versions, so there is no "legacy format" concern for database-stored properties.

### Marking Properties for Encryption

To encrypt a property value via the admin console:

1. Navigate to Server → Server Manager → System Properties
2. Find the property you want to encrypt
3. Click Edit Property
4. Check the Encrypt property value checkbox
5. Click Save Property

The property value will be encrypted the next time it is saved.

## Which Properties to Encrypt

### Good Candidates for Encryption

The following property types should be encrypted:

- Database passwords
- LDAP/Active Directory bind passwords
- Email/SMTP server passwords
- API keys and tokens
- Integration service passwords
- OAuth client secrets

### Properties That Should NOT Be Encrypted

Not all properties benefit from encryption. Non-sensitive values should remain unencrypted for easier troubleshooting and debugging:

- Server names and hostnames
- Port numbers
- Feature flags (boolean settings)
- Timeout values
- Cache size settings
- Log levels

Best practice: Only encrypt values that represent credentials or secrets. Over-encryption makes troubleshooting more difficult without providing additional security benefits.

## Automatic Security Upgrades (XML Properties Only)

Note: This section applies only to properties stored in `openfire.xml`. Database properties (stored in the `ofProperty` table) have used random IVs for several major versions and do not require upgrading.

### Legacy XML Encryption Format

Older versions of Openfire (pre 5.1) used a weaker encryption method for XML properties that could be vulnerable to pattern analysis attacks. Properties encrypted with the legacy method lack the `iv` attribute.

Example of a legacy encrypted property:

    <password encrypted="true">EncryptedValue</password>

### Automatic Upgrade Process

Openfire automatically upgrades legacy encrypted properties to use stronger encryption when they are accessed. This happens transparently during normal operation:

1. Openfire reads a property with legacy encryption
2. The value is decrypted using the legacy method
3. The value is immediately re-encrypted using the modern method with a random IV
4. The configuration is updated with the new encrypted value

No administrator action is required. The upgrade happens automatically and does not interrupt service.

### Monitoring Upgrades

Openfire logs when properties are auto-upgraded. Look for log entries like:

    Auto-upgrading legacy encrypted property 'database.defaultProvider.password' to use random IV

Once all properties have been upgraded, these log messages will no longer appear.

## Security Limitations

### What Property Encryption Protects

Property encryption protects credentials at rest in configuration files and database backups. It prevents:

- Casual viewing of passwords in configuration files
- Accidental exposure when configuration files are shared or committed to version control
- Password leakage in database backups

### What Property Encryption Does NOT Protect Against

Property encryption is not a complete security solution. It does NOT protect against:

- Users with access to the Java process memory – Passwords are decrypted in memory during normal operation and can be extracted by users who can attach debuggers or dump process memory
- Users with root/administrator access to the server – They can extract the encryption keys from `security.xml` and decrypt all properties
- Network eavesdropping – Use TLS to protect credentials in transit (see TLS Guide)
- Compromised admin accounts – Whilst administrators cannot view encrypted property values, they can change them to attacker-controlled values, potentially causing denial of service
- Malicious code running on the server – Any code running with Openfire's permissions can decrypt properties

Defense in depth: Property encryption is one layer in a comprehensive security strategy. Combine it with proper access controls, network security, regular security updates, and monitoring for best protection.

## Backup and Restore Considerations

### Understanding Encryption Keys

Encrypted properties can only be decrypted using the correct encryption keys from `conf/security.xml`. By default, each Openfire server generates its own unique encryption keys on first startup, but keys can be shared between servers if needed (for example, in clustered deployments where maintaining consistent keys simplifies operations, or when migrating between servers).

### Backup Procedures

When backing up Openfire, always include:

- `conf/openfire.xml` – Configuration including encrypted properties
- `conf/security.xml` – Encryption keys
- Database backup (if using external database)
- `embedded-db/` directory (if using embedded database)

### Restore Scenarios

#### Restoring to the same server

Works normally. The existing encryption keys will decrypt all properties.

#### Restoring to a different server (same installation)

If you previously copied `security.xml` to maintain consistent keys, restore will work normally.

#### Restoring to a different server (different installation)

You must restore `conf/security.xml` along with `conf/openfire.xml` to maintain the correct encryption keys. Without matching keys:

- Encrypted properties cannot be decrypted
- Openfire may fail to start (if database password cannot be decrypted)
- You will need to reconfigure all encrypted properties manually

### Disaster Recovery Best Practice

Always test your backup and restore procedures before a disaster occurs. Verify that you can successfully restore Openfire and that all encrypted properties decrypt correctly.

## Configuration Options

### Disabling Automatic Upgrades (XML Properties)

The auto-upgrade feature only affects XML properties in `openfire.xml`. In rare cases, you may want to disable it (for example, to maintain exact configuration file compatibility during troubleshooting or for controlled migration testing).

To disable auto-upgrade, add a Java system property to the Openfire startup configuration:

1. Edit the Openfire startup script (for example):
   - Linux/Unix: `bin/openfire.sh`
2. Add the following Java system property:

       -Dopenfire.xmlproperties.encryption.autoupgrade=false

3. Restart Openfire

Warning: Disabling automatic upgrades is not recommended for production systems. Legacy encryption is less secure and should only be used for backward compatibility testing or during controlled migration periods.

### Re-enabling Automatic Upgrades

To re-enable automatic upgrades:

1. Remove the `-Dopenfire.xmlproperties.encryption.autoupgrade=false` property from the startup script
2. Or change it to `-Dopenfire.xmlproperties.encryption.autoupgrade=true`
3. Restart Openfire

Automatic upgrades are enabled by default and do not require explicit configuration.

## Troubleshooting

### Property Won't Decrypt After Restore

Symptom: After restoring from backup, Openfire cannot decrypt properties. You may see errors like "Failed to decrypt property" or Openfire fails to start.

Solution: Restore `conf/security.xml` from the same backup to restore the encryption keys that were used to encrypt the properties.

### Auto-Upgrade Not Working

Symptom: Legacy encrypted properties remain in the old format and are not being upgraded.

Solution:

1. Check that auto-upgrade is not disabled in the startup script (`openfire.xmlproperties.encryption.autoupgrade` system property)
2. Check logs for warnings about disabled auto-upgrade
3. Verify the property is actually being accessed (auto-upgrade happens on first access)

### Encryption Keys Lost

Symptom: `security.xml` was deleted or corrupted and encrypted properties cannot be decrypted.

Solution: Unfortunately, without the encryption keys, encrypted properties cannot be recovered. You will need to:

1. Restore `security.xml` from backup, or
2. Manually reconfigure all encrypted properties (database passwords, LDAP passwords, etc.)

This is why it's critical to include `security.xml` in your backup procedures.

## Further Reading

For additional security topics, see:

- TLS Guide – Certificate management and secure connections
- LDAP Integration Guide – Securing LDAP authentication
- Recovery of an Admin Password – Regaining admin access