用Mcryptencryption/解密文件

试图编写一些函数来encryption或解密一个文件,并使用这里find的类来尝试完成这个工作:

http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Library-libmcrypt

下面的encryption函数似乎可以工作,因为它看起来是encryption文件并将其放置在预期的目录中。 我试图解密文件现在,它只是与消息“无法完成解密”(这是编码在那里…)在PHP错误日志没有什么,所以我不知道为什么它失败,但是因为mcrypt对我来说是全新的,所以我更倾向于相信我在这里做错了什么。

这里是function:

//ENCRYPT FILE function encryptFile() { global $cryptastic; $pass = PGPPASS; $salt = PGPSALT; $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key."); if ($handle = opendir(PATH.'/ftpd')) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { $newfile = PATH.'/encrypted/'.$file.'.txt'; $msg = file_get_contents(PATH.'/ftpd/'.$file); $encrypted = $cryptastic->encrypt($msg, $key) or die("Failed to complete encryption."); $nfile = fopen($newfile, 'w'); fwrite($nfile, $encrypted); fclose($nfile); unlink(PATH.'/ftpd/'.$file); } } closedir($handle); } //DECRYPT FILE function inFTP() { global $cryptastic; $pass = PGPPASS; $salt = PGPSALT; $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key."); if ($handle = opendir(PATH.'/encrypted')) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { $newfile = PATH.'/decrypted/'.$file; $msg = PATH.'/encrypted/'.$file; $decrypted = $cryptastic->decrypt($msg, $key) or die("Failed to complete decryption."); $nfile = fopen($newfile, 'w'); fwrite($nfile, $decrypted); fclose($nfile); //unlink(PATH.'/encrypted/'.$file); } } closedir($handle); } //$crypt->decrypt($file); } 

尝试使用mcryptencryption这个PHP5类。 在这种情况下,它使用AESencryption。 您将需要更改每个使用它的站点的密钥。 如果你至less不使用它,它可能会引导你编写你自己的版本。

 <?php class Encryption { const CIPHER = MCRYPT_RIJNDAEL_128; // Rijndael-128 is AES const MODE = MCRYPT_MODE_CBC; /* Cryptographic key of length 16, 24 or 32. NOT a password! */ private $key; public function __construct($key) { $this->key = $key; } public function encrypt($plaintext) { $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM); $ciphertext = mcrypt_encrypt(self::CIPHER, $this->key, $plaintext, self::MODE, $iv); return base64_encode($iv.$ciphertext); } public function decrypt($ciphertext) { $ciphertext = base64_decode($ciphertext); $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); if (strlen($ciphertext) < $ivSize) { throw new Exception('Missing initialization vector'); } $iv = substr($ciphertext, 0, $ivSize); $ciphertext = substr($ciphertext, $ivSize); $plaintext = mcrypt_decrypt(self::CIPHER, $this->key, $ciphertext, self::MODE, $iv); return rtrim($plaintext, "\0"); } } 

用法:

 $key = /* CRYPTOGRAPHIC!!! key */; $crypt = new Encryption($key); $encrypted_string = $crypt->encrypt('this is a test'); $decrypted_string = $crypt->decrypt($encrypted_string); // this is a test 

笔记:

  • 这个类不适合用于二进制数据(可能以NUL字节结尾)
  • 这个类不提供authenticationencryption。

虽然约翰的答案是好的,但使用base64编码只是为了解决二进制安全问题是矫枉过正,将使您的encryption文件比原来的33%大。 这里是我的PHP实现的AES Crypt文件格式,它透明地解决了所有上述问题。

https://github.com/philios33/PHP-AES-File-Encryption

它是二进制安全的,包含authenticationencryption。 由于它使用开源的crypt文件格式(.aes),它与其他.aes软件完全兼容。

https://www.aescrypt.com/

界面非常简单,无论您是encryption还是解密。 你只要给它一个源文件和密码。

CakePHP有一个很好的实现 rijndael。 我不直接在这里发布代码,因为不确定的法律后果。

这里是 Security::rijndael()方法的api文档 。

如果对一个文件进行编码,你需要在调用这个方法前用' encrypt '调用base64_encode() ,用' decrypt '调用这个方法后调用base64_decode()

你不应该使用Mcrypt来encryption/解密数据。 正如你的问题所显示的,在接受的答案中,数据没有被authentication,这意味着它将成为select密文攻击的受害者。

此外,已经做了大量努力来确保开发者正确地将密码原语组合在一起。 因此,而不是Mcrypt,您应该为您的PHP项目使用libsodium。 libsodium是NaCl的一个分支。 NaCl / libsodium是为了消除开发人员发现的许多密码陷阱,例如使用MAC标记validation的定时攻击。

Mcrypt在PHP 7.1中被弃用,libsodim是PHP中处理encryption的首选方式。

在你的PHP项目中使用libsodium很容易,也很安全。 Scott Arciszewski在https://paragonie.com/book/pecl-libsodium上使用libsodium编写了大量电子书。; 任何人在做PHP密码学都是值得的。