PHP 中的 AES-256 加密

问题描述 投票:0回答:5

我需要一个 PHP 函数

AES256_encode($dataToEcrypt)
$data
加密为 AES-256,另一个
AES256_decode($encryptedData)
则执行相反的操作。有谁知道这个函数应该有什么代码?

php security encryption aes encryption-symmetric
5个回答
18
投票

查看mcrypt模块

AES-Rijndael 示例取自此处

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

这是解密功能


18
投票

我需要一个 PHP 函数

AES256_encode($dataToEcrypt)
$data
加密为 AES-256,另一个
AES256_decode($encryptedData)
则执行相反的操作。有谁知道这个函数应该有什么代码?

加密和编码之间存在差异

真的需要AES-256吗?与 AES-128 相比,AES-256 的安全性并不那么重要;你更有可能在协议层搞砸而不是被黑客攻击,因为你使用的是 128 位分组密码而不是 256 位分组密码。

重要 - 使用图书馆

快速而肮脏的 AES-256 实施

如果您有兴趣构建自己的不是为了在生产中部署它而是为了您自己的教育,我提供了一个示例 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
        );
    }
}

使用方法

首先,生成两个密钥(是的,是两个)并以某种方式存储它们。

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

然后加密/解密消息:

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

如果您没有

random_bytes()
,请获取 random_compat


15
投票

MCRYPT_RIJNDAEL_256 不等于 AES_256。

让 RIJNDAEL 从 AES 解密的方法是使用 MCRYPT_RIJNDAEL_128 并在加密之前填充要加密的字符串

AES-256 的块大小 = 128 位,密钥大小 = 256 位 Rijndael-256 的 BlockSize=256bit 和 KeySize=256bit

只是 AES/Rijndael 128 位是相同的。 Rijndael-192 和 Rijndael-256 与 AES-192 和 AES-256 不同(块大小和轮数不同)。


0
投票

您可以使用 PHP 中的

password_hash
函数加密和解密数据。您还需要一个成本函数。确保您的 PHP 环境中启用了 OpenSSL 和 Mcrypt 扩展。

<?php
$plaintext = 'My secret message 1234';
$password = '3sc3RLrpd17';
$method = 'aes-256-cbc';

$key = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

// IV must be exact 16 chars (128 bit)
$iv = random_bytes(16);

$encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
$decrypted = openssl_decrypt(base64_decode($encrypted), $method, $key, OPENSSL_RAW_DATA, $iv);

echo 'plaintext=' . $plaintext . "\n";
echo 'cipher=' . $method . "\n";
echo 'encrypted to: ' . $encrypted . "\n";
echo 'decrypted to: ' . $decrypted . "\n\n";
?>
  • $plaintext
    :该变量保存我们要加密的消息。在 在这个例子中,“我的秘密消息1234”是明文。
  • $password
    :在这里,我们定义用于导出的密码 加密密钥。
  • $method
    :我们将加密方法设置为 “aes-256-CBC”,即 Cipher Block 中的 AES-256 加密模式 链接(CBC)模式。
  • $key
    :代码生成加密 密钥使用提供的密码,利用password_hash() 具有 PASSWORD_BCRYPT 算法和成本因子的函数 12.
  • $iv
    :CBC 模式下的 AES-256 需要初始化向量 (IV),且长度必须恰好为 16 字节(128 位)。
  • $encrypted
    :使用加密得到的密文 openssl_encrypt() 函数,接受明文,加密 方法、加密密钥、IV 和其他参数。密文是 然后进行 Base64 编码以方便表示。
  • $decrypted
    :至 确保解密过程有效,我们使用 openssl_decrypt() 函数来反转加密过程。这将返回原始的 解码 Base64 表示后的明文。

来源:PHP 中的安全 AES-256 加密和解密


-2
投票
$key = '324325923495kdfgiert734t'; // key used for decryption in jasper code
$text = 'string_to_be_encrypted';
$encrypted = fnEncrypt($text, $key);




function fnEncrypt( $plaintext, $key )
{
$plaintext = pkcs5_pad($plaintext, 16);

return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, hex2bin($key), $plaintext, MCRYPT_MODE_ECB));

}


function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}



function hex2bin($hexdata) 
{
$bindata = "";

    for ($i = 0; $i < strlen($hexdata); $i += 2) 
    {
      $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
    }

return $bindata;
}
© www.soinside.com 2019 - 2024. All rights reserved.