当前位置: 首页 > 工具软件 > GnuPG > 使用案例 >

gnupg 和gnupg2_使用GnuPG保守秘密

陆耀
2023-12-01

gnupg 和gnupg2

GnuPG stands for GNU Privacy Guard, a form of public key cryptography based on the OpenPGP standard. This article will show you how to perform a few essential tasks with GnuPG using PHP and the GnuPG PECL extension.

GnuPG代表GNU Privacy Guard ,这是一种基于OpenPGP标准的公共密钥加密形式。 本文将向您展示如何使用PHP和GnuPG PECL扩展对GnuPG执行一些基本任务。

For our purposes, as someone who would like to transmit and receive encrypted messages, you need three keys: your own public key, your own private key, and the public key of the person that you would like to communicate with.

就我们的目的而言,作为一个想要发送和接收加密消息的人,您需要三个密钥:您自己的公共密钥,您自己的私有密钥以及您想要与之通信的人的公共密钥。

Private keys should never be shared, but your own is required to generate an encrypted message. Public keys can and must be distributed. Your public key is required by anyone who wishes to encrypt a message intended for your eyes only or to decrypt a message that you have sent them. The public key cannot be used to forge a signature or decrypt messages meant only for you.

私钥绝对不应共享,但需要您自己的私钥才能生成加密的消息。 可以并且必须分配公共密钥。 任何希望加密仅用于您的眼睛的消息或解密已发送给您的消息的人都需要您的公共密钥。 公用密钥不能用于伪造签名或解密仅适合您的消息。

GnuPG also serves as a means to verify the authenticity of non-encrypted data via encrypted signatures, but that topic is not covered here.

GnuPG还用作通过加密签名来验证非加密数据的真实性的方法,但是此处不涉及该主题。

The GnuPG extension discussed here depends on the GnuPG installation on whatever machine you are working with along with the configuration of the user account under which the code will run. The examples provided here are intended to be run from the command line and will interact with the GnuPG environment of the user running them. It should be trivial to extend the concepts here to work from a web script.

此处讨论的GnuPG扩展取决于您正在使用的任何计算机上的GnuPG安装以及将在其下运行代码的用户帐户的配置。 此处提供的示例旨在从命令行运行,并将与运行它们的用户的GnuPG环境进行交互。 扩展此处的概念以通过Web脚本工作应该是微不足道的。

产生金钥 (Generating Keys)

Before you can do anything with GnuPG, you must have a private/public key pair. Though the PECL extension does not let you create these keys right from PHP, you can easily do this from the command line with the gpg command, or a friendly GUI frontend for whatever OS you choose. In Linux, all you need is:

在使用GnuPG进行任何操作之前,必须具有私钥/公钥对。 尽管PECL扩展不允许您直接从PHP创建这些键,但是您可以使用gpg命令或友好的GUI前端从命令行轻松地执行此操作,无论您选择哪种操作系统。 在Linux中,您需要做的是:

gpg --gen-key

After answering a few easy questions about your identity, selecting a passphrase for use of your private key, and accepting the defaults for everything else, your GnuPG keyring will be generated. The keyring stores your keys and the keys of anyone that you plan to interact with.

在回答了一些有关您的身份的简单问题,选择了使用私钥的密码并接受了其他所有内容的默认设置后,将生成您的GnuPG密钥环。 密钥环存储您的密钥以及您计划与之交互的任何人的密钥。

Once generated, your keyring is automatically populated with your first private/public keys. You should export a copy of both your public and private keys and keep them in a safe place so that you can reuse the same keys in all future interactions with GnuPG. You may also want to consider publishing your public key to a key server to make it available in a safe way to anyone who needs it. More information about GnuPG tools and key servers can be found on the gnupg website.

生成密钥后,将自动用您的第一个私钥/公钥填充密钥环。 您应该导出公钥和私钥的副本,并将其保存在安全的地方,以便将来在与GnuPG的所有交互中都可以重用相同的密钥。 您可能还需要考虑将您的公共密钥发布到密钥服务器,以使其以安全的方式提供给需要它的任何人。 可以在gnupg网站上找到有关GnuPG工具和密钥服务器的更多信息。

导出密钥 (Exporting Keys)

One way to export your GnuPG public key is with PHP. Before you can perform the export however, you must find the key “fingerprint” of your new public key. Every key in your keyring will have a fingerprint that is used as a unique identifier. To list them all, loop through a gnupg_keylistiterator() object:

导出GnuPG公钥的一种方法是使用PHP。 但是,在执行导出之前,您必须找到新公共密钥的密钥“指纹”。 钥匙圈中的每个钥匙都会有一个指纹,用作唯一标识符。 要列出所有内容,请遍历gnupg_keylistiterator()对象:

<?php
$iter = new gnupg_keylistiterator();
foreach ($iter as $fingerprint => $user) {
    print "$fingerprint: $usern";
}

For the keyring of a user named “testuser” on my workstation, the above code results in the following output:

对于我的工作站上名为“ testuser”的用户的密钥环,以上代码将导致以下输出:

6436010991C352981F95F9A5D5AF916244CD449B: Test User (This is a test account) <test@example.com>

The key itself is binary data, so to actually encode and print an ASCII version of the public key we need some new code:

密钥本身是二进制数据,因此要实际编码和打印ASCII版本的公共密钥,我们需要一些新代码:

<?php
$gpg = new gnupg();
$export = $gpg->export("6436010991C352981F95F9A5D5AF916244CD449B");
print $export;

This creates a new gnupg object, and uses the export() method to export the public key corresponding to the provided fingerprint. In my case, the test user’s key is:

这将创建一个新的gnupg对象,并使用export()方法导出与提供的指纹相对应的公钥。 就我而言,测试用户的密钥是:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2 (GNU/Linux)

mQGiBFDP4+cRBACupVdbSBVa5wLjKFoELiS9IunzQA6hj2P1jCYmXtwSPwvvrXRX
LqhpkmXmWrHvo+4WW8aDjI2csuh8z4gNB+YGkaB3iKZxyhdazKco0R1BU7fjPrUn
4iqVqkpaixcdMVDPkjjBTJDEdjxWWieErSzbzkjy8wuTJR+lAVFWTcuTOwCg9WAg
bLwpPIlcULQ+D/l3sLt2AaED/jgdcTvMsVG96xZGWT9bewl/HVX+2ZpCWIkbE34E
AABS8c9hwNEz3QvkEqoxcf5sC8ujtvTf3Gky4E6h4KZrpCZuZ8kFRQiAhqP6XwNi
8jJM0BK8ooYPFP4UsfRQImc4XczL/njtwpwJ8wX2UOb7oglJB5acMulvzpD4cRvK
FkqIA/9NzGFExUeJeJ8b6GC17KDOIHfBwlrcGvc85c574fUVekV9jGGaAzl6i89O
OIWQCELH9s8quTA23tDeMcHRwUMHAYxh7lf2stoJmwz0IySpUCkmxcUhB5TIzBOB
jHifGAlJKby6gNJhlvghTxXlVGsQiM14JLJo2+hS2qMc17vp77QyVGVzdCBVc2Vy
IChUaGlzIGlzIGEgdGVzdCBhY2NvdW50KSA8dGVzdEB0ZXN0LmNvbT6IYAQTEQIA
IAUCUM/j5wIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJENWvkWJEzUSb6iIA
nRhCMJ3CN+1QXSD2zAtsoWgVebqZAKDLp1636WZ3XZAIVOlHBnpMTfcdA7kCDQRQ
z+PwEAgAkRnVYvmbpkGCCU8T56Wh2+jMA5GVPbPuyqmprfvgrt7yp9EEXfXRrGVA
KYMbFDU4+Vdc2U9Wm/T6P7McvI3dJARWOD6NeqOh+k6yTYxH+qznsU2d/7+Vugfx
zxVXtllhpnyWc5AlAr6yo98UdjO+q5RNM3fzSdjHth+MCJqEBfkyTui2VN9odnnS
IkDFHJyVcaUfQ580RpLWllwAC3+Urntc02S6xxEr03fKIe/wuhXC9gpG5lWu3hyj
k0PlsSh55w5gb4zF3Q2yDbToAuvSg1My0ytIPddmjjBx8gs4PCnB+48R52jsT/uI
Ju6j83Ddy1Ph1cnalChIpMit2Hm40wADBQf+J+NRhzLByj3YRsRK9ohZ0dm1+sMU
S86Xv676IQMgTzohFCAicnFZtTJx6N35pox/azOOGxAoof79TPv1r897bysAXjmu
qjW2mMpAfhnNY18Wf2SB+R7oYsID/z4fOQltyX54z8Fi40OO6UtI1X3Lh4KGzhUK
AnkgVeYGxupiK2HHtxeknEiKuAY+RXiQRYIC8YgAZboKqbWt8WVSMwctLbtRgXQC
VlkcZzwPk+mPocxYcnID+mZgIpwX0/+Zs4OOlyrf1k1oI6zQA7tJ+etGugtee78j
e8gub9CYvyCJMFM3pI5OEKC9BRSjPjgSw/6kQEc4bHP1Bn4WqPgh2d61Q4hJBBgR
AgAJBQJQz+PwAhsMAAoJENWvkWJEzUSbAhYAoKnL/nGFmJejtoPdws+QRW95VECn
AJ4yFFV1axpTDbIClQQTerJS7xpxjg==
=g/FY
-----END PGP PUBLIC KEY BLOCK-----

The extension only permits us to export the public key, so if you would like to export your private key in a similar fashion for backup purposes then you’ll need to use the GnuPG tool itself.

该扩展名仅允许我们导出公钥,因此,如果出于备份目的以类似方式导出私钥,则需要使用GnuPG工具本身。

导入密钥 (Importing Keys)

We now have three keys as required for a private exchange. We’ve generated our own public/private keys, and you have the public key for testuser above that we’ll use as a third party public key.

现在,我们有三个私钥交换所需的密钥。 我们已经生成了自己的公钥/私钥,并且您拥有上面的testuser的公钥,我们将其用作第三方公钥。

To communicate with testuser, we’ll need to get her public key into our keyring. Importing a public key can be done by passing the public key to the import() method:

要与测试用户通信,我们需要将她的公钥放入我们的密钥环。 可以通过将公钥传递给import()方法来import()公钥:

<?php
$keydata = "FULL PUBLIC KEY FROM ABOVE";
$gpg = new gnupg();
$info = $gpg->import($keydata);

You can verify that this key has been added to your keyring on the command line with gpg --list-keys and use the gnupg_keylistiterator() example from earlier to get the fingerprint.

您可以使用gpg --list-keys验证此密钥已添加到命令行gpg --list-keys并使用前面的gnupg_keylistiterator()示例获取指纹。

加密邮件 (Encrypting Messages)

With all of our keys in our keyring, we can encrypt an important message for testuser. The message contains the answer to the question:

将所有密钥都放在密钥环中,我们可以为测试用户加密一条重要消息。 该消息包含问题的答案:

Q: How many programmers does it take to change a lightbulb?

问:更换灯泡需要多少程序员?

We’ll use testuser’s public key to ensure that she will be the only person able to decrypt the answer. The code for encrypting the answer is:

我们将使用测试用户的公共密钥来确保她将是唯一能够解密答案的人。 用于加密答案的代码是:

<?php
$gpg = new gnupg();
$gpg->addencryptkey("6436010991C352981F95F9A5D5AF916244CD449B");
$enc = $gpg->encrypt("A: None, that is a hardware problem!");
print $enc;

We use addencryptkey() to specify which public key to encrypt this message with, which should be the recipient’s key, not the sender’s. In this case it is the public key fingerprint of testuser.

我们使用addencryptkey()指定用于加密此消息的公用密钥,该公用密钥应该是收件人的密钥,而不是发送者的密钥。 在这种情况下,它是测试用户的公钥指纹。

Once encrypted, nobody will be able to decrypt the message unless they have testuser’s private key in their keyring… which should be no one other than testuser herself.

加密后,除非他们在密钥环中具有测试用户的私钥,否则任何人都将无法解密该消息……测试用户本人应该别无其他。

解密消息 (Decrypting Messages)

From the other side, once testuser receives the message, she can use the code below to decrypt the secret answer:

另一方面,一旦测试用户收到消息,她就可以使用以下代码解密秘密答案:

<?php
$encrypted = "THE UNREADABLE ENCRYPTED MESSAGE SHOULD BE PASTED HERE";
$gpg = new gnupg();
$gpg->adddecryptkey("6436010991C352981F95F9A5D5AF916244CD449B","test1234");
$plain = $gpg->decrypt($encrypted);
print $plain;

The encrypted message is stored in $encrypted. We create a new gnupg() object, specify which of testuser’s keys should be used for decrypting the message by fingerprint and our private key password, and then print the decrypted message. It is important to mention that decrypting a message will always require the recipient to enter the password that they associated with the private key in addencryptkey(), except in gnupg v2 where you cannot enter a plain text password in the code – you will be prompted for a password while running this code in the CLI. If you plan to use this function in a web based tool with gnupg v2, you might want to consider excluding the passphrase on the web user’s private key.

加密的消息存储在$encrypted 。 我们创建一个新的gnupg()对象,通过指纹我们的私钥密码指定应使用哪个testuser的密钥解密消息,然后打印解密的消息。 重要的是要提及,解密消息将始终要求收件人在addencryptkey()输入与私钥相关联的密码,但在gnupg v2中除外,在该版本中,您无法在代码中输入纯文本密码-系统将提示您在CLI中运行此代码时输入密码。 如果打算在gnupg v2的基于Web的工具中使用此功能,则可能要考虑在Web用户的私钥上排除密码短语。

收盘时 (In Closing)

Now that we know how to encrypt and decrypt with GnuPG, why would you want to in PHP? With SSL you can secure data transmitted between a web server and client, and SSH can be used to secure shell sessions, so why something else?

既然我们知道如何使用GnuPG进行加密和解密,那么为什么要用PHP? 使用SSL,您可以保护Web服务器和客户端之间传输的数据的安全,而SSH可用于保护Shell会话的安全,那么为什么还要其他呢?

Sometimes you need information to be secure, not only while it is in transit, but also where it is stored and all layers in between. Maybe you need to transmit financial information to a remote location; can you trust system administrators or those who have physical access at the location? Or perhaps a project requires you to transfer data using an insecure protocol, such as FTP.

有时,不仅在传输过程中,而且在存储位置及其之间的所有层,您都需要安全的信息。 也许您需要将财务信息传输到远程位置; 您可以信任系统管理员或该位置具有物理访问权限的管理员吗? 或者项目可能要求您使用不安全的协议(例如FTP)来传输数据。

While our simple examples above are useful for transferring encrypted messages, GPG and the gnupg extension can also be used to validate the authenticity of unencrypted messages by the use of signatures. Email is also a notoriously insecure method of communication and messages are easily forged, and though not described in detail here, using encryption and encrypted signatures ensures security and authenticity.

尽管上面的简单示例对于传输加密的消息很有用,但是GPG和gnupg扩展名也可以用于通过使用签名来验证未加密消息的真实性。 电子邮件也是众所周知的不安全的通信方法,并且容易伪造消息,尽管这里没有详细描述,但使用加密和加密签名可以确保安全性和真实性。

I encourage you to further explore the GnuPG tool options and concepts if you’re writing an application that calls for serious data security.

如果您正在编写要求严格的数据安全性的应用程序,我鼓励您进一步探索GnuPG工具的选项和概念。

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/keeping-secrets-safe-with-gnupg/

gnupg 和gnupg2

 类似资料: