php - 使用mcrypt加密/解密字符串和文件

时间:2015-06-19 02:38:41

标签: php security encryption cryptography aes

我不时会遇到创建用于加密/解密PHP中的字符串和文件的函数的任务。 我决定最终确定这些功能,并进行了一些搜索,但我找不到足够的资源来确认这些功能的安全性。

请注意,除非必要,否则我不想使用另一个完整的库,我不明白为什么PHP提供OpenSSL& mcrypt函数但没有人真正实现它们。

我能够找到these个函数,但它们没有被注释,有些步骤不清楚(它们也没有生成密钥但使用预定义的密钥)。 在这些函数之后,我还发现了this stackoverflow问题,但第一个答案使用了另一个库,而第二个使用了ECB。

编辑:我更新了之前使用mcrypt的代码示例,只使用了评论中建议的OpenSSL:

function generate_key($cipher = 'AES-256-CBC')
{
    return base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher))); // Generate a random key - currently using the function for the vector length
}
function encrypt($data, $key, $cipher = 'AES-256-CBC')
{
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher)); // Generate a random initialization vector
    return base64_encode($iv) . '$' . openssl_encrypt($data, $cipher, base64_decode($key), false, $iv); // Return a base64 encoded string containing the iv and the encrypted data
}
function decrypt($data, $key, $cipher = 'AES-256-CBC')
{
    $data = explode('$', $data); // Explode the previously encoded string

    if(count($data) == 2)
        return openssl_decrypt($data[1], $cipher, base64_decode($key), false, base64_decode($data[0])); // Decrypt the data given key and the iv
    else
        return false;
}

我使用这些函数测试了加密和解密:

$input = 'Hello world!';
echo 'Original data: ' . $input . '<br /><br />';

$key = generate_key();
$encrypted = encrypt($input, $key);
echo 'Key used for encryption: ' . $key . '<br />';
echo 'Encrypted data: ' . $encrypted . '<br /><br />';

$decrypted = decrypt($encrypted, $key);
echo 'Decrypted data: ' . $decrypted . '<br />';

问题:如上所示,OpenSSL是否正确实施?它们也可以用于文件吗?

这些是使用mcrypt的旧功能。 不要再使用它们了。

function generate_key($cipher = MCRYPT_RIJNDAEL_256)
{
    return bin2hex(openssl_random_pseudo_bytes(mcrypt_get_key_size($cipher, MCRYPT_MODE_CBC))); // Generate a random key using OpenSSL with size given from mcrypt depending on cipher
}
function encrypt($data, $key, $cipher = MCRYPT_RIJNDAEL_256)
{
    $iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher, MCRYPT_MODE_CBC)); // Generate random initialization vector with size given from mcrypt depending on cipher
    return bin2hex($iv) . '$' . bin2hex(mcrypt_encrypt($cipher, pack('H*', $key), $data, MCRYPT_MODE_CBC, $iv)); // Return the initialization vector and encrypted data as ASCII string
}
function decrypt($data, $key, $cipher = MCRYPT_RIJNDAEL_256)
{
    $data = explode('$', $data); // Split the input data by $ to retrieve the initialization vector and the encrypted data

    if(count($data) == 2) // Check if there are 2 parts after splitting by $
        return mcrypt_decrypt($cipher, pack('H*', $key), pack('H*', $data[1]), MCRYPT_MODE_CBC, pack('H*', $data[0])); // Return the decrypted string
    else
        return false; // Return false if the given data was not properly formatted (no $)
}

1 个答案:

答案 0 :(得分:-1)

目前的最佳做法是avoid using mcrypt in favor of openssl

速度基准,openssl is pretty much faster