Search code examples
phpencryptionmcrypt

How to do symmetric cryptography without hardcoded key in PHP


I'm using the PHP mcrypt library to cryptograph and store (MySQL) data using AES.

I was wondering if there is a good way to do this without having a hardcoded encryption/decryption key in my code.

If a hacker gets access to my server he will be able to see the files and my key on the code, therefore accessing all the data on the database.

Thanks.


Solution

  • I'm using the PHP mcrypt library to cryptograph and store (MySQL) data using AES.

    You may wish to reconsider your choice in cryptography library.

    I was wondering if there is a good way to do this without having a hardcoded encryption/decryption key in my code.

    Store it in a configuration file outside your document root? For example, defuse/php-encryption.

    If a hacker gets access to my server he will be able to see the files and my key on the code, therefore accessing all the data on the database.

    If a hacker gets access to your server, symmetric-key encryption cannot save you. Public-key encryption, however, can preserve confidentiality.

    Using Halite, this is easy to solve:

    1. You can only encrypt on the server; never decrypt.
    2. Your secret key must be kept offline and used by a human.

    Online Code (Assumes PHP 7.0 and Halite 2.1)

    <?php
    declare(strict_types=1);
    use ParagonIE\Halite\{
        Asymmetric\Crypto as Asymmetric,
        KeyFactory
    };
    
    $publicKey = KeyFactory::loadEncryptionPublicKey("/path/to/public/key");
    $encrypted = Asymmetric::seal("Whatever secret data we want", $publicKey);
    // Now do whatever you need with $encrypted
    

    Offline Code (Assumes PHP 7.0 and Halite 2.1)

    <?php
    declare(strict_types=1);
    use ParagonIE\Halite\{
        Asymmetric\Crypto as Asymmetric,
        KeyFactory
    };
    
    $salt = ""; // Generate from random_bytes(16) once, then persist.
    $password = ""; // Create a strong password
    
    $keyPair = KeyFactory::deriveEncryptionKeyPair($password, $salt);
    $secretKey = $keyPair->getSecretKey();
    $publicKey = $keyPair->getPublicKey();
    
    // To have the public key to a file to upload to the server:
       KeyFactory::save($publicKey, '/path/to/public/key');
    
    $decrypted = Asymmetric::unseal($encrypted, $secretKey);