Encriptado / Desencriptado

Phalcon proporciona un servicio de cifrado mediante el componente Phalcon\Crypt. Esta clase ofrece una envoltura simple orientada a objetos a la biblioteca de cifrado openssl de PHP.

De forma predeterminada, este componente proporciona cifrado seguro utilizando AES-256-CFB.

El algoritmo de cifrado AES-256 es utilizado entre otros en SSL/TLS a través de Internet. Se considera entre los mejores cifradores. En teoría no es manipulable ya que las combinaciones de claves son enormes. Aunque la NSA la ha categorizado en la Suite B, también ha recomendado el uso de claves de encriptación de 128-bit y superiores.

Debe utilizar una clave del largo correspondiente al algoritmo actual. Por defecto, para el algoritmo utilizado es 32 bytes.

Si el algoritmo para calcular el resumen (firma) no es seleccionado durante la construcción del objeto, aes-256-cfb es seleccionada por defecto. {.alert.alert-warning}

Uso básico

Este componente está diseñado para ser muy fácil de usar:

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

/**
 * Establecer el algoritmo de cifrado.
 *
 * El cifrado `aes-256-gcm' es el preferido, pero no se puede utilizar
 * hasta que la librería openssl este actualizada. Disponible desde PHP 7.1.
 *
 * El `aes-256-ctr' es posiblemente la mejor opción de algoritmo de cifrado
 * en estos días.
 */
$crypt->setCipher('aes-256-ctr');

/**
 * Establecer la clave de encriptación.
 *
 * El `$key' debe ser generado previamente de una manera criptográficamente segura.
 *
 * Clave insegura:
 * "mi password"
 *
 * Mejor (pero aún insegura):
 * "#1dj8$=dp?.ak//j1V$~%*0X"
 *
 * Clave segura:
 * "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
 *
 * Utiliza tu propia clave. No copiar y pegar esta clave de ejemplo.
 */
$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";

$text = 'Este es el texto que deseas encriptar.';

$encrypted = $crypt->encrypt($text, $key);

echo $crypt->decrypt($encrypted, $key);

También puede establecer el algoritmo y si se debe calcular un resumen del mensaje (firma) durante la construcción del objeto. Esto elimina la necesidad de llamar a setCipher() y useSigning():

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt('aes-256-ctr', true);

$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";

$text = 'This is the text that you want to encrypt.';

$encrypted = $crypt->encrypt($text, $key);

echo $crypt->decrypt($encrypted, $key);

Puede utilizar la misma instancia para encriptar/desencriptar varias veces:

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

$crypt->setCipher('aes-256-ctr');

// ¡Utilice sus propias claves!
$texts = [
    "T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c" => 'Este es un texto secreto',
    "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3" => 'Esto es muy secreto',
];

foreach ($texts as $key => $text) {
    // Realizar la encriptación
    $encrypted = $crypt->encrypt($text, $key);

    // Ahora descencriptar
    echo $crypt->decrypt($encrypted, $key);
}

Para mayor seguridad, puede indicar al componente que calcule un resumen del mensaje basado en uno de los algoritmos admitidos devueltos por getAvailableHashAlgos. Como puede verse, este algoritmo se puede establecer durante la instanciación del objecto pero también se puede establecer después.

NOTA Calculando el resumen del mensajes (firma) estará activado por defecto a partir de Phalcon 4.0.0 o superior.

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

$crypt->setCipher('aes-256-ctr');
$crypt->setHashAlgo('aes-256-cfb');

// Forzar el calculo del resumen del mensaje basado en el algoritmo Hash
$crypt->useSigning(true);

$key  = "T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c";
$text = 'This is a secret text';

// Realizar encriptación
$encrypted = $crypt->encrypt($text, $key);

// Ahora desencriptar
echo $crypt->decrypt($encrypted, $key);

Opciones de encriptado

Las siguientes opciones están disponibles para cambiar el comportamiento de cifrado:

Nombre Descripción
Cipher Cipher es uno de los algoritmos de encriptación soportados por openssl. Ver una lista aquí

Ejemplo:

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

// Usar blowfish
$crypt->setCipher('bf-cbc');

// ¡Usar tu propia clave!
$key  = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'Este es un texto secreto';

echo $crypt->encrypt($text, $key);

Si desea cmoprobar los algoritmos disponibles en su sistema, puede llamar al método getAvailableHashAlgos().

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

// Obtener algoritmos disponibles
$algorithms = $crypt->getAvailableHashAlgos();

var_dump($algorithms);

Soporte Base64

Para que el cifrado se transmita correctamente (correos electrónicos) o se muestre (navegadores), generalmente se aplica el cifrado base64 a textos:

<?php

use Phalcon\Crypt;

// Crear una instancia
$crypt = new Crypt();

// ¡Usar tu propia clave!
$key  = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'Este es un texto secreto';

$encrypt = $crypt->encryptBase64($text, $key);

echo $crypt->decryptBase64($encrypt, $key);

Configurando el servicio de encriptación

Puede configurar el componente de encriptación en un contenedor de servicios para su uso desde cualquier parte de la aplicación:

<?php

use Phalcon\Crypt;

$di->set(
    'crypt',
    function () {
        $crypt = new Crypt();

        // Establecer una clave de encriptación global
        $crypt->setKey(
            "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
        );

        return $crypt;
    },
    true
);

Entonces, por ejemplo, en un controller usted puede utilizarlo de la siguiente manera:

<?php

use Phalcon\Mvc\Controller;

class SecretsController extends Controller
{
    public function saveAction()
    {
        $secret = new Secrets();

        $text = $this->request->getPost('text');

        $secret->content = $this->crypt->encrypt($text);

        if ($secret->save()) {
            $this->flash->success(
                '¡Secreto creado correctamente!'
            );
        }
    }
}

Enlaces