使用PHP创建加密的zip存档

使用PHP创建加密的zip存档,php,encryption,zip,Php,Encryption,Zip,我正在寻找一种将.txt文件加密为zip文件的方法,但要采用安全的密码保护方式。我的目标是通过电子邮件将此文件发送给我,而没有人能够阅读附件的内容 有谁知道一个简单的,最重要的,安全的方法来实现这一点吗?我可以创建zip档案,但我不知道如何加密它们,或者,这有多安全 注意:此答案建议使用已知的加密方法 不安全,即使有良好的密码。请 和。支持php中的AES zip加密 到达时带有(和),这意味着 答案也将很快过时。直到那时 您可以使用以下选项: <?php echo system('zip

我正在寻找一种将.txt文件加密为zip文件的方法,但要采用安全的密码保护方式。我的目标是通过电子邮件将此文件发送给我,而没有人能够阅读附件的内容

有谁知道一个简单的,最重要的,安全的方法来实现这一点吗?我可以创建zip档案,但我不知道如何加密它们,或者,这有多安全

注意:此答案建议使用已知的加密方法 不安全,即使有良好的密码。请 和。支持php中的AES zip加密 到达时带有(和),这意味着 答案也将很快过时。直到那时

您可以使用以下选项:

<?php echo system('zip -P pass file.zip file.txt'); ?>

其中pass是密码,file.txt将压缩为file.zip。这应该可以在Windows和Linux上使用,您只需要获得免费版本的zip for Windows()


这种安全性可能会被暴力攻击、字典攻击等破坏。但这并不是那么容易,特别是如果你选择了一个长且难以猜测的密码。

越来越多的工具支持AES加密的ZIP文件。它工作正常,很安全

EDIT2:您可以使用fromPHP从PHP动态生成AES加密的zip归档文件。DotNetZip是一个为.NET语言(C#、VB等)设计的.NET库。它只在Windows上运行:(。但是DotNetZip做AES,并且是免费的,它可以从PHP工作

这是我使用的代码。(Win32上的PHPV5.2.9)

我就是这样做的。
这是一个excel,但它是一样的

  • 让php创建一个随机的代码名
  • 将代码名保存在db或retrieve.php包含的文件中
  • 把代号寄给你自己

  • 通过web访问retrieve.php?codename=[codename]

  • 让php检查代码名是否正确(甚至可能是年龄)
  • 从需要发送给您的数据在内存中创建excel/text文件
  • 通过添加一个带有代码名的本地密码(只有您知道)来创建一个加密代码。(我说add,但也可以是mixed、xor-ed或substr…)
  • 使用创建的加密代码动态加密
  • 从数据库或配置文件中删除代码名
  • 在邮件中返回此加密文档(压缩或不压缩大小)
  • 也许可以在邮件中添加代码名的前两个字符,以了解要使用的本地完整代码名

  • 使用本地解密脚本对下载的文件进行解码。使用相同的代码名/密码算法创建解密密钥

我用的是胡言乱语。(

因为这样我就可以在客户端解码器上使用javascript(用于我想在浏览器中快速浏览的内容)。

尽管PHP是一种成熟的语言,但没有足够的方法(不包括自定义扩展或类似的方法)来用纯PHP实现如此简单的任务

您还可以做的是等待,直到可以用于生产(因为实现了(感谢Pierre和Remi))

但是,在此之前,您还可以尝试将>=1.14.0移植到PHP<7.2,但目前没有可用的已编译二进制文件,因此您必须自己编译它,并在可能的情况下尝试(我相信是这样)

PS我想试试,但是我的电脑上现在没有VS2015+。

从php 7.2(一个小时前发布)开始,正确的方法是使用本机php代码中包含的其他功能。(感谢您指出这一变化即将到来)

现在,简单的答案如下:

<?php
$zip = new ZipArchive();
if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) { 
     //being here means that we were able to create the file..

     //setting this means that we do not need to pass in a password to every file, this will be the default
    $zip->addFile('thing3.txt');

    //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_128);
    //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_192);
    //you should just use ZipArchive::EM_AES_256 unless you have super-good reason why not. 
    $zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_256, 'password_for_thing3');

     $zip->addFile('thing4.txt');
    //or you can also use the index (starting at 0) of the file...
    //which means the following line should do the same thing...
    //but just referencing the text.txt by index instead of name..
    //$zip->setEncryptionIndex(1, ZipArchive::EM_AES_256, 'password_for_thing_4'); //encrypt thing4, using its index instead of its name...

    $zip->close();
    echo "Added thing3 and thing4 with two different passwords\n";
} else {
    echo "KO\n";
}
?>

但您也可以按索引而不是名称设置加密方法,您可以按每个文件设置每个密码……还可以使用

本例练习这些更复杂的选项



由于libzip 1.2.0引入了对加密的支持,因此启用了对zip加密的底层支持。因此,您需要使用PHP7.2和libzip 7.2才能运行此代码……希望这篇说明在回答“real soon”时会显得粗糙

谢谢,我会试试这个。我正在使用的是linuxserver,因此不需要附加组件。ZIP加密实际上非常弱,有些攻击会产生一个可用的密码(如果不一定与最初使用的密码相同的话)在相对较短的时间内。此答案非常危险。此答案使用的加密非常弱。它不是基于现代AES的加密。许多托管环境会阻止“系统”函数。使用ZipArchive类更好。不确定需要什么样的安全性。但先加密,然后给自己发送一个压缩文件可能是更好的方法。或者甚至给自己发送一个链接,在访问该链接时按需创建文件。你知道我如何在php脚本中使用它吗?非常感谢!如果你在Windo上运行phpws,有一个DotNetZip()支持AES加密的Zip。PHP可以调用.NET组件。badda bing,badda boom。不幸的是,我的大多数服务器都运行在linux上。但是我可以在windows上使用这个解决方案。非常感谢!我会用乱七八糟的AES PHP.Zip加密数据(或者不),下载并运行本地cli php脚本进行解密。还有一个乱七八糟的aes的javascript实现,因此客户端也可以是javascript。()这是一个很好的答案。但是现在PHP7.2中提供了支持,应该会有所降低……哇,这实际上是可行的。非常违反直觉的是,您必须为每个文件分别设置加密主题。
<?php
$zip = new ZipArchive();
if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) {
    $zip->setPassword('secret_used_as_default_for_all_files'); //set default password

    $zip->addFile('thing1.txt'); //add file
    $zip->setEncryptionName('thing1.txt', ZipArchive::EM_AES_256); //encrypt it

    $zip->addFile('thing2.txt'); //add file
    $zip->setEncryptionName('thing2.txt', ZipArchive::EM_AES_256); //encrypt it

    $zip->close();

    echo "Added thing1 and thing2 with the same password\n";
} else {
    echo "KO\n";
}
?>
<?php
$zip = new ZipArchive();
if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) { 
     //being here means that we were able to create the file..

     //setting this means that we do not need to pass in a password to every file, this will be the default
    $zip->addFile('thing3.txt');

    //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_128);
    //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_192);
    //you should just use ZipArchive::EM_AES_256 unless you have super-good reason why not. 
    $zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_256, 'password_for_thing3');

     $zip->addFile('thing4.txt');
    //or you can also use the index (starting at 0) of the file...
    //which means the following line should do the same thing...
    //but just referencing the text.txt by index instead of name..
    //$zip->setEncryptionIndex(1, ZipArchive::EM_AES_256, 'password_for_thing_4'); //encrypt thing4, using its index instead of its name...

    $zip->close();
    echo "Added thing3 and thing4 with two different passwords\n";
} else {
    echo "KO\n";
}
?>