web-dev-qa-db-fra.com

Chiffrement AES-256 en PHP

J'ai besoin d'une fonction PHP, AES256_encode($dataToEcrypt) pour crypter le $data En AES-256 et une autre AES256_decode($encryptedData) fait l'inverse. quelqu'un sait-il quel code ces fonctions devraient avoir?

23
mariannnn

Regardez le module mcrypt

Exemple AES-Rijndael tiré de ici

$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";

C'est la fonction de décryptage

15
Fabio

J'ai besoin d'une fonction PHP, AES256_encode($dataToEcrypt) pour crypter le $data En AES-256 et une autre AES256_decode($encryptedData) fait l'inverse. Quelqu'un sait-il quel code ces fonctions devraient avoir?

Il y a différence entre le cryptage et le codage .

Avez-vous vraiment besoin d'AES-256? La sécurité d'AES-256 par rapport à AES-128 n'est pas si importante; vous êtes plus susceptible de bousiller la couche de protocole que d'être piraté parce que vous avez utilisé un chiffrement par bloc de 128 bits au lieu d'un chiffrement par bloc de 256 bits.

Important - Utilisez une bibliothèque

A flowchart for PHP users

Une implémentation AES-256 rapide et sale

Si vous êtes intéressé à construire votre propre non pas pour le déployer en production mais plutôt pour votre propre éducation, j'ai inclus un échantillon 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
        );
    }
}

Usage

Tout d'abord, générez deux clés (oui, deux d'entre elles) et stockez-les d'une manière ou d'une autre.

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

Puis pour crypter/décrypter les messages:

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

Si vous n'avez pas random_bytes(), obtenez random_compat .

14
Scott Arciszewski

MCRYPT_RIJNDAEL_256 n'est pas équivalent à AES_256.

La façon de faire décrypter RIJNDAEL à partir d'AES est d'utiliser MCRYPT_RIJNDAEL_128 et de remplir la chaîne pour crypter avant de crypter

AES-256 a BlockSize = 128 bits et KeySize = 256 bits Rijndael-256 a BlockSize = 256 bits et KeySize = 256 bits

Seuls AES/Rijndael 128 bits sont identiques. Rijndael-192 et Rijndael-256 ne sont pas identiques à AES-192 et AES-256 (les tailles de blocs et le nombre de tours diffèrent).

13
Behzad-Ravanbakhsh