Saltar al contenido

Cifrado AES-256 en PHP

Nuestros mejores programadores agotaron sus depósitos de café, por su búsqueda día y noche por la resolución, hasta que Alexandría encontró la contestación en GitLab y hoy la compartimos aquí.

Solución:

Mira el módulo mcrypt

Ejemplo de AES-Rijndael tomado de aquí

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
# and 256 respectively
$key_size =  strlen($key);
echo "Key size: " . $key_size . "n";
$text = "Meet me at 11 o'clock behind the monument.";
echo strlen($text) . "n";

$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
echo strlen($crypttext) . "n";

Esta es la función de descifrado

Necesito una función de PHP, AES256_encode($dataToEcrypt) para cifrar el $data en AES-256 y otro AES256_decode($encryptedData) haz lo contrario ¿Alguien sabe qué código debe tener esta función?

Hay una diferencia entre cifrar y codificar.

Vos si De Verdad ¿Necesita AES-256? La seguridad de AES-256 versus AES-128 no es tan significativa; es más probable que te equivoques en la capa de protocolo que te pirateen porque usaste un cifrado de bloque de 128 bits en lugar de un cifrado de bloque de 256 bits.

Importante: use una biblioteca

Un diagrama de flujo para usuarios de PHP

  • desactivar/php-cifrado
  • libsodio PECL
  • Halita (envoltura de libsodio, ahora estable)

Una implementación rápida y sucia de AES-256

Si estás interesado en construir tu propio no por el hecho de implementarlo en producción pero más bien por el bien de su propia educación, he incluido una muestra AES256

/**
 * This is a quick and dirty proof of concept for StackOverflow.
 * 
 * @ref http://stackoverflow.com/q/6770370/2224584
 * 
 * Do not use this in production.
 */
abstract class ExperimentalAES256DoNotActuallyUse

    /**
     * Encrypt with AES-256-CTR + HMAC-SHA-512
     * 
     * @param string $plaintext Your message
     * @param string $encryptionKey Key for encryption
     * @param string $macKey Key for calculating the MAC
     * @return string
     */
    public static function encrypt($plaintext, $encryptionKey, $macKey)
    
        $nonce = random_bytes(16);
        $ciphertext = openssl_encrypt(
            $plaintext,
            'aes-256-ctr',
            $encryptionKey,
            OPENSSL_RAW_DATA,
            $nonce
        );
        $mac = hash_hmac('sha512', $nonce.$ciphertext, $macKey, true);
        return base64_encode($mac.$nonce.$ciphertext);
    

    /**
     * Verify HMAC-SHA-512 then decrypt AES-256-CTR
     * 
     * @param string $message Encrypted message
     * @param string $encryptionKey Key for encryption
     * @param string $macKey Key for calculating the MAC
     */
    public static function decrypt($message, $encryptionKey, $macKey)
    
        $decoded = base64_decode($message);
        $mac = mb_substr($message, 0, 64, '8bit');
        $nonce = mb_substr($message, 64, 16, '8bit');
        $ciphertext = mb_substr($message, 80, null, '8bit');

        $calc = hash_hmac('sha512', $nonce.$ciphertext, $macKey, true);
        if (!hash_equals($calc, $mac)) 
            throw new Exception('Invalid MAC');
        
        return openssl_decrypt(
            $ciphertext,
            'aes-256-ctr',
            $encryptionKey,
            OPENSSL_RAW_DATA,
            $nonce
        );
    

Uso

Primero, genera dos keys (sí, dos de ellos) y almacenarlos de alguna manera.

$eKey = random_bytes(32);
$aKey = random_bytes(32);

Luego, para cifrar/descifrar mensajes:

$plaintext = 'This is just a test message.';
$encrypted = ExperimentalAES256DoNotActuallyUse::encrypt($plaintext, $eKey, $aKey);
$decrypted = ExperimentalAES256DoNotActuallyUse::decrypt($encrypted, $eKey, $aKey);

si no tienes random_bytes()obtenga compatibilidad_aleatoria.

MCRYPT_RIJNDAEL_256 no es equivalente a AES_256.

La forma de descifrar RIJNDAEL de AES es usar MCRYPT_RIJNDAEL_128 y rellenar el string cifrar antes de cifrar

AES-256 tiene BlockSize=128bit y KeySize=256bit Rijndael-256 tiene BlockSize=256bit y KeySize=256bit

Solo AES/Rijndael de 128 bits son idénticos. Rijndael-192 y Rijndael-256 no son idénticos a AES-192 y AES-256 (los tamaños de bloque y el número de rondas difieren).

Más adelante puedes encontrar los comentarios de otros usuarios, tú todavía puedes mostrar el tuyo si lo crees conveniente.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *