在 PHP 中使用 PGP 加密文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15969740/
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
Encrypt files using PGP in PHP?
提问by Prashant
I want to use PGP encryption to encrypt a CSV files, I am generating through a PHP script and then send that file to client via email. Client will give me the encryption key, which I need to use for encryption files.
我想使用 PGP 加密来加密 CSV 文件,我通过 PHP 脚本生成,然后通过电子邮件将该文件发送给客户端。客户端会给我加密密钥,我需要用它来加密文件。
I Googled about PGP and found it is Pretty Good Privacy, also I found OpenPGP http://www.openpgp.org/and GnuPG http://www.gnupg.org/What are these two types of PGP? and which one should I use?
我在谷歌上搜索了 PGP 并发现它是非常好的隐私,我还发现了 OpenPGP http://www.openpgp.org/和 GnuPG http://www.gnupg.org/这两种类型的 PGP 是什么?我应该使用哪一种?
Also how to encrypt a files using PGP in PHP with the key that my client will provide?
另外如何使用我的客户端提供的密钥在 PHP 中使用 PGP 加密文件?
I have heard this term first time, can anyone please help in understanding this and implementing this in PHP.
我第一次听说这个词,任何人都可以帮助理解这一点并在 PHP 中实现这一点。
回答by Jens Erat
Question 1: About PGP
问题 1:关于 PGP
- PGP(Pretty Good Privacy) is a product and trademark of Symantec Corporation (they bought it some years ago).
- OpenPGPis the standard used by PGP.
- GnuPG(Gnu Privacy Guard) is a free and open source implementation of PGP.
- PGP(Pretty Good Privacy)是赛门铁克公司的产品和商标(他们几年前买的)。
- OpenPGP是 PGP 使用的标准。
- GnuPG(Gnu Privacy Guard)是 PGP 的免费开源实现。
So what you want to do is encrypt to an OpenPGPkey. Which implementation of OpenPGP your client uses to decrypt the data is not important for you. With PHP, commonly GnuPG is used and there are interfaces built-in.
所以你想要做的是加密到一个OpenPGP密钥。您的客户端使用哪种 OpenPGP 实现来解密数据对您来说并不重要。PHP一般使用GnuPG,内置接口。
Question 2: Using GnuPG in PHP
问题 2:在 PHP 中使用 GnuPG
Use the GnuPG interface, which is an extension that can be installed for PHP.
使用GnuPG 接口,这是一个可以为 PHP 安装的扩展。
At first, import the key, where $keydata
is the ASCII armored public key:
首先,导入密钥,这里$keydata
是ASCII装甲公钥:
<?php
$gpg = new gnupg();
$info = $gpg -> import($keydata);
print_r($info);
?>
Then use this key to encrypt the data, this time using the client's key's fingerprint:
然后使用此密钥加密数据,这次使用客户端的密钥指纹:
<?php
$gpg = new gnupg();
$gpg -> addencryptkey("8660281B6051D071D94B5B230549F9DC851566DC");
$enc = $gpg -> encrypt("just a test");
echo $enc;
?>
If you want to encrypt files, read and pass them to encrypt()
. Be sure to use at least long key IDs (eg. DEADBEEFDEADBEEF
), better fingerprints (as in the example) when referencing keys; and never use short key IDs (DEADBEEF
), as those are vulnerable to collision attacks.
如果要加密文件,请读取它们并将其传递给encrypt()
. DEADBEEFDEADBEEF
在引用密钥时,请务必至少使用长密钥 ID(例如)、更好的指纹(如示例中所示);并且永远不要使用短密钥 ID ( DEADBEEF
),因为它们容易受到碰撞攻击。
The is a more comprehensive example for doing bothadded by a user in the PHP manual.
这是用户在 PHP 手册中添加的更全面的示例。
回答by Dean Or
Going to leave an answer here as many examples across the net for PHP GnuPG are very bare bones and hopefully this saves someone some frustration.
在这里留下一个答案,因为网络上的许多 PHP GnuPG 示例都非常简单,希望这可以避免一些人的挫败感。
Basically, it mirrors how the GnuPG command line tool works. You need to import a key if it's not already in gpg's key ring then you need to select the recipient's key to use for encryption/decryption.
基本上,它反映了 GnuPG 命令行工具的工作方式。如果它不在 gpg 的密钥环中,您需要导入一个密钥,然后您需要选择收件人的密钥以用于加密/解密。
gpg --import recipients-public-key.asc
gpg -r recipient --encrypt test.txt
If you did what I did and passed in the key as the recipient it doesn't work!
如果您按照我所做的操作并将密钥作为收件人传递,则它不起作用!
It's not clear what this field is in either the GPG manualor PHP documentationwhich refers to this field as "fingerprint". Check gpg's key ring for your freshly imported key with:
在GPG 手册或PHP 文档中都不清楚这个字段是什么,将这个字段称为“指纹”。使用以下命令检查 gpg 的密钥环以获取新导入的密钥:
gpg --list-keys
This will output something like this:
这将输出如下内容:
pub rsa2048 2019-04-14 [SC] [expires: 2021-04-14]
0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA
uid [ultimate] Dean Or
sub rsa2048 2019-04-14 [E] [expires: 2021-04-14]
This will give you the UID and on the second line the fingerprint associated with every key. As far as I can tell you can use the UID and fingerprint as the recipient.
这将为您提供 UID,并在第二行提供与每个键关联的指纹。据我所知,您可以使用 UID 和指纹作为收件人。
So your PHP code to encrypt might look like this:
因此,您要加密的 PHP 代码可能如下所示:
// Encrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient public key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-public-key.asc');
}
$gpg->addencryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
echo $gpg->encrypt('This is a test!');
Then the recipient's code will look like this:
然后收件人的代码将如下所示:
// Decrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient private key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-private-key.asc');
}
$gpg->adddecryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA', '');
echo $gpg->decrypt($encyptedMessage);
Note the fingerprints are the same for both the recipient's public and private key.
请注意,收件人的公钥和私钥的指纹相同。
There is also a known issue with adddecryptkey not taking a passphrase! You either need to remove the passphrase or change your version of GnuPG.
adddecryptkey 还存在一个已知问题,即不使用密码!您需要删除密码或更改您的 GnuPG 版本。