2015-06-19 60 views
1

我时不时地开始创建用于在PHP中加密/解密字符串和文件的函数。 我决定最终确定这些功能并做了一些搜索,但是我找不到足够的资源来确认这些功能的安全性。php - 使用mcrypt对字符串和文件进行加密/解密

请注意,我不想使用另一个成熟的库,除非有必要,我不明白为什么PHP提供了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

你*问题*的含义有点模糊。你在寻找是/否的答案,这是否安全?你问是否mcrypt和openssl版本是相同的?你问如何确定openssl中的密钥大小?请澄清你的问题。 StackOverflow不适用于是/否问题和讨论。另外,请每个帖子坚持一个问题。 –

+2

我是使用另一个库的第一个答案的作者。您可能还想看到[这个答案](http://stackoverflow.com/a/30189841/2224584),它解释了在PHP中实现经过身份验证的对称密钥加密的过程。它还演示了如何使用OpenSSL([请勿使用mcrypt](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-重新做-IT-错))。 –

+0

@ArtjomB。你是对的。原来的问题有点失落。我会更新它。问题在于功能是否正确(它们不是),以及它们是否可以/应该如何用于文件。您的评论和Scott Arciszewskis评论已经帮助了很多人。我会考虑根据Scotts链接优化第二组函数。 – user1137183

回答

-1

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

和速度基准,其中openssl is pretty much faster

+0

注意。我尝试将上面的函数转换为纯OpenSSL,但函数mcrypt_create_iv和mcrypt_get_key_size似乎没有相同之处。我如何在OpenSSL中创建一个IV,并为选定的密码获取适当的密钥大小? PS:第二个链接是错误的。 – user1137183

+0

使用openssl_random_pseudo_bytes(最好将第二个参数设置为TRUE)。这将产生具有适当随机性特征的IV。关于关键尺寸我不太确定,但它不会很难谷歌。 – venca

+0

我用OpenSSL版本更新了这个问题。我找不到确定密钥大小的“OpenSSL-way”,因此我现在使用了矢量大小。为什么OpenSSL使用16字节作为IV,而mcrypt使用32字节,尽管两者都使用AES-256-CBC,是否有原因? – user1137183

相关问题