Skip to content
This repository was archived by the owner on Aug 31, 2025. It is now read-only.

The EncryptService

Nicholas K. Dionysopoulos edited this page Apr 17, 2018 · 2 revisions

Available since 3.3.2

Many times we find ourselves wanting to save sensitive or personally identifiable in the database. When this information needs to be searchable there is not much else we can do about it. However, in most cases the information we need to store doesn't need to be searchable, just retrievable. In these cases we should be using encryption.

Encryption vs Hashing. Encryption can be reversed: I can get the original text from the encrypted text. Hashing is irreversible by nature: I cannot get the original text from the hash. Joomla, WordPress and others abusively call hashed passwords "encrypted". If you are looking for "password encryption" this is NOT the correct place to look into. This service provides real encryption, of the reversible. DO NOT use it for storing passwords!

The EncryptService, exposed by the crypto service of the FOF component Container, is a simple way to manage cryptography of text handled by your component.

How to use

The service is designed to be dead simple to use.

Encrypting data: $encrypted = $container->crypto->encrypt($originalData);

Decrypting data: $decrypted = $container->crypto->decrypt($encryptedData);

Key management happens automatically. Read below for more information.

Under the hood

Your data is encrypted using AES-128 (technically: Rijndael-128 which is the same algorithm) in CBC mode with an AES-128 encryption key derived from a static key (password) using PBKDF2. The AES-128 encryption is seeded with a truly random IV, generated with a crypto-safe PRNG.

The static key is read from a PHP constant. The name of the constant is configurable. The constant can be either defined in your component code executing before the first use of the service or, as is the default behavior, stored in a file under your component's backend directory. The name of the file is configurable.

If the key constant is not defined and the key file does not exist a new, truly random secret key is generated upon using the service and stored in the key file.

It is important to remember that the crypto service is not instantiated until you try to retrieve it from the container (since the FOF container is, in fact, a service locator). As a result nothing will happen until your code with $container->crypto executes. This maintains backwards compatibility, i.e. not trying to create key files for components which don't use the crypto service.

Configuration

The configuration options for the crypto service can be found in the fof.xml documentation under the Container configuration header.

Advanced configuration

It is possible to use the crypto service without creating a key file. In this case we just need to provide the key constant ourselves.

WARNING! Don't provide a key stored in your database for encrypting data stored in the database. The whole point of the encryption layer is to provide protection against an attacker who has obtained read access to your database, e.g. through an SQL Injection vulnerability in your component, a third party extension or Joomla! itself. If you store both the encrypted data and the encryption key in the database the attacker has anything required to read your secrets, nullifying the whole point of using encryption. Likewise, don't use a key file if you are encrypting data on disk; if the attacker gets read only access to your filesystem you're done for. Finally note that if the attacker can read both the files and the database data of your site you have been fully compromised and NOTHING can help you. If you are trying to use encryption as mitigation for a complete compromise STOP NOW; what you are doing is insecure and, to be perfectly honest, just plain stupid.

Let's say that you want to use Joomla's secret key for encrypting data. In your container you should override the constructor with something like:

public function __construct(array $values = array())
{
    parent::__construct($values);

    define('MYCOMPONENT_FOF_ENCRYPT_SERVICE_SECRETKEY', $this->platform->getConfig()->get('secret', ''));
}

Of course if you have set up a different constant in your fof.xml file you need to adapt your define accordingly.

Caveat: the Joomla secret value is something which is meant to be safe to change and, in fact, it is encouraged to change it every time you transfer or clone your site. This is something that Akeeba Backup will do automatically every time you transfer a site. Therefore relying on the Joomla secret value may render your data unreadable after restoring / transferring your site.

Clone this wiki locally