PHP 中的 AES-256 加密
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6770370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AES-256 encryption in PHP
提问by mariannnn
I need a PHP function, AES256_encode($dataToEcrypt)
to encrypt the $data
into AES-256 and another one AES256_decode($encryptedData)
do the opposite. Does anyone know what code should this functions have?
我需要一个 PHP 函数,AES256_encode($dataToEcrypt)
将其加密$data
为 AES-256,而另一个函数AES256_decode($encryptedData)
则相反。有谁知道这个函数应该有什么代码?
采纳答案by Fabio
Look at the mcrypt module
AES-Rijndael example taken from here
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";
This is the decrypt function
这是解密函数
回答by Scott Arciszewski
I need a PHP function,
AES256_encode($dataToEcrypt)
to encrypt the$data
into AES-256 and another oneAES256_decode($encryptedData)
do the opposite. Does anyone know what code should this functions have?
我需要一个 PHP 函数,
AES256_encode($dataToEcrypt)
将其加密$data
为 AES-256,而另一个函数AES256_decode($encryptedData)
则相反。有谁知道这个函数应该有什么代码?
There is a difference between encrypting and encoding.
Do you reallyneed AES-256? The security of AES-256 versus AES-128 isn't that significant; you're more likely to screw up at the protocol layer than get hacked because you used a 128-bit block cipher instead of a 256-bit block cipher.
你真的需要AES-256吗?AES-256 与 AES-128 的安全性并不那么重要;你更有可能在协议层搞砸而不是被黑客攻击,因为你使用了 128 位分组密码而不是 256 位分组密码。
Important - Use A Library
重要 - 使用图书馆
- defuse/php-encryption
- PECL libsodium
- Halite(libsodium wrapper, now stable)
- defuse/php 加密
- PECL 钠
- 岩盐(libsodium包装,现在稳定)
A Quick and Dirty AES-256 Implementation
快速而肮脏的 AES-256 实现
If you're interested in building your own not for the sake of deploying it in productionbut rather for the sake of your own education, I've included a sample AES256
如果您有兴趣构建自己的不是为了在生产中部署它而是为了您自己的教育,我已经包含了一个示例 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
用法
First, generate two keys (yes, two of them) and store them somehow.
首先,生成两个密钥(是的,其中两个)并以某种方式存储它们。
$eKey = random_bytes(32);
$aKey = random_bytes(32);
Then to encrypt/decrypt messages:
然后加密/解密消息:
$plaintext = 'This is just a test message.';
$encrypted = ExperimentalAES256DoNotActuallyUse::encrypt($plaintext, $eKey, $aKey);
$decrypted = ExperimentalAES256DoNotActuallyUse::decrypt($encrypted, $eKey, $aKey);
If you don't have random_bytes()
, get random_compat.
如果没有random_bytes()
,请获取random_compat。
回答by Behzad-Ravanbakhsh
MCRYPT_RIJNDAEL_256is not equivalent to AES_256.
MCRYPT_RIJNDAEL_256不等同于 AES_256。
The way to make RIJNDAEL be decrypted from AES is to use MCRYPT_RIJNDAEL_128 and padd the string to encrypt before encrypting
使 RIJNDAEL 从 AES 解密的方法是使用 MCRYPT_RIJNDAEL_128 并在加密之前填充字符串进行加密
AES-256 has BlockSize=128bit and KeySize=256bit Rijndael-256 has BlockSize=256bit and KeySize=256bit
AES-256 的 BlockSize=128bit 和 KeySize=256bit Rijndael-256 的 BlockSize=256bit 和 KeySize=256bit
Just AES/Rijndael 128bit are identical. Rijndael-192 and Rijndael-256 are not identical to AES-192 and AES-256 (block sizes and number of rounds differ).
只是 AES/Rijndael 128 位是相同的。Rijndael-192 和 Rijndael-256 与 AES-192 和 AES-256 不同(块大小和轮数不同)。
回答by sourav
$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;
}