简体   繁体   English

在 PHP 中使用 PGP 加密文件?

[英]Encrypt files using PGP in PHP?

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.我想使用 PGP 加密来加密 CSV 文件,我通过 PHP 脚本生成,然后通过 email 将该文件发送到客户端。 Client will give me the encryption key, which I need to use for encryption files.客户会给我加密密钥,我需要用它来加密文件。

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?我在 Google 上搜索了 PGP,发现它的隐私非常好,我还发现 OpenPGP http://www.openpgp.org/和 GnuPG http://www.gnupg.org/这两种 PGP 是什么? and which one should I use?我应该使用哪一个?

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 中实现它。

Question 1: About PGP问题一:关于PGP

  • PGP (Pretty Good Privacy) is a product and trademark of Symantec Corporation (they bought it some years ago). PGP (Pretty Good Privacy)是赛门铁克公司的产品和商标(他们在几年前购买了它)。
  • OpenPGP is the standard used by PGP. OpenPGP是 PGP 使用的标准。
  • GnuPG (Gnu Privacy Guard) is a free and open source implementation of PGP. GnuPG (Gnu Privacy Guard)是 PGP 的免费开源实现。

So what you want to do is encrypt to an OpenPGP key.所以你想要做的是加密到一个OpenPGP密钥。 Which implementation of OpenPGP your client uses to decrypt the data is not important for you.您的客户端使用哪种 OpenPGP 实现来解密数据对您来说并不重要。 With PHP, commonly GnuPG is used and there are interfaces built-in.在 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() .如果要加密文件,请读取并将它们传递给encrypt() Be sure to use at least long key IDs (eg. DEADBEEFDEADBEEF ), better fingerprints (as in the example) when referencing keys;确保在引用键时至少使用长键 ID(例如DEADBEEFDEADBEEF )、更好的指纹(如示例中); and never use short key IDs ( DEADBEEF ), as those are vulnerable to collision attacks .并且永远不要使用短密钥 ID ( DEADBEEF ),因为它们很容易受到碰撞攻击


The is a more comprehensive example for doing both added by a user in the PHP manual.这是用户在 PHP 手册中添加的更 全面的示例

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.基本上,它反映了 GnuPG 命令行工具的工作方式。 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.如果密钥不在 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 manual or PHP documentation which refers to this field as "fingerprint".GPG 手册PHP 文档中不清楚这个字段是什么,将这个字段称为“指纹”。 Check gpg's key ring for your freshly imported key with:检查 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.这将为您提供 UID,并在第二行提供与每个键关联的指纹。 As far as I can tell you can use the UID and fingerprint as the recipient.据我所知,您可以使用 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! adddecryptkey 不使用密码也有一个已知问题! You either need to remove the passphrase or change your version of GnuPG.您需要删除密码或更改您的 GnuPG 版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM