GPG-GNU Privacy Guard教程(命令行加密和解密)

时间:2020-03-21 11:43:55  来源:igfitidea点击:

在本教程中,我们将讨论GPG(GNU隐私保护),这是一种非常可靠的方法,可用于加密,解密以及对发送和接收的数据和消息进行身份验证。

GPG是开源的,并已获得GPL(通用公共许可证)的许可。
可以使用两种类型的加密。
一种是对称加密,另一种是非对称加密。
在对称加密中,使用相同的密钥进行加密和解密,这意味着发送方和接收方都必须具有相同的密钥。
为了使对称加密有效,对称密钥(将由双方使用,并用于加密和解密)必须共享。

这带来了另一个安全风险。
我们将如何共享该对称密钥,因为如果攻击者获得了该密钥,那么加密就没有用了。
为了解决这个问题,引入了非对称加密(公钥密码术)。
在非对称加密中,每个用户都有两个密钥。
一个是公钥,另一个是私钥。

如果要以非对称加密方式将一些加密数据发送到接收器,则需要具有接收器的公钥。
而且,如果接收方必须向我们发送一些加密的消息,那么他必须拥有公共密钥。
因此,参与通信的双方必须彼此拥有对方的公钥。

使用公钥加密的任何内容都只能使用相应的私钥解密(安全保存且完全不共享)。
因此,如果我们在接收者的公用密钥的帮助下将某些加密的消息发送给接收者,则接收者只能打开/解密该消息,因为他只有相应的私有密钥。
因此,公钥将与所有可以向我们发送消息的人共享,并且如果我们想向他们发送加密的消息,则需要拥有他们的公钥。
公钥最有趣的部分是,即使发送者使用接收者的公钥对消息加密后,也无法解密该消息(只有接收者才能使用其私钥对其进行解密)。
因此,密钥始终被制成密钥对。

公钥总是相对于私钥构造的。
让我们看看它在GPG中是如何工作的。

我们需要在Linux中拥有一个名为gnupg的软件包才能使用gpg。
大多数Linux发行版都默认安装了此版本。
我将在Red Hat Systems上使用gnupg显示此示例教程。

[root@myvm1 ~]# rpm -qa | grep gnupg
gnupg-1.4.5-14
[root@myvm1 ~]#

为了在GPG的帮助下确保通信的安全,我们需要首先创建一个密钥对。
创建密钥对非常简单,但是这里要了解的重要事实是,正在使用哪种算法,以及它们之间的区别是什么。
我们在旅途中,对概念的信任远胜于命令。
通过查看手册页或者文档文件可以轻松找到命令,但是,概念和了解事物的工作方式需要进行广泛的研究,有时还需要更深入地dig掘才能发现问题。

让我们借助gpg命令中的--gen-key参数创建密钥对。

[root@myvm1 ~]# gpg --gen-key
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.
Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign only)
Your selection?

现在,让我们了解输出中的每个选项。
--gen-key参数为我们提供了三个选择表单的选项。
他们每个人都有自己的差异。

(1)DSA和Elgamal(默认)

这是在gpg中生成密钥对时获得的第一个选项。
并其中显示了将被选择的默认选项。
这意味着,如果在选择过程中仅按Enter键,则默认情况下将选择DSA和Elgamal的第一个选项。
默认密钥对取决于我们使用的gnupg的版本,因此,如果我们使用的是其他版本的gnupg,则它可能与上面显示的示例有所不同。

第一个选项将创建两个密钥对。
一对DSA密钥对和一对Elgamal密钥对。
在此之前,我们需要先了解一些知识。
DSA仅用于数字签名。

数字签名可用于检查两件事。

  • 验证发件人
  • 要验证该消息并确认它没有被更改/更改。

可以在私钥的帮助下进行数字签名,并可以通过相应的公钥验证签名。
通常,发件人正在发送的整个消息/数据永远不会被签名,因为对整个消息进行签名会增加开销。

签名整个消息的更好的替代方法是签名消息/数据的加密哈希。

注意:加密散列函数用于验证数据的完整性,并检查数据是否被更改。
使用加密哈希函数的主要优点是,哈希对于特定数据始终是唯一的。
更改数据中的任何字符都会产生不同的哈希值。

有许多正在使用的哈希算法。
其中DSA签名算法使用SHA1(由于SHA1涉及安全问题,有时使用SHA2)

像DSA这样的数字签名的主要优点是,没有人可以伪造任何人的签名,因为这需要私钥。
但是,是的,任何拥有公钥的人都可以验证签名的数据。

因此,选择DSA和Elgamal的第一个选项将生成两个钥匙圈。
一种用于加密(Elgamal),另一种用于数字签名(DSA)。

(2)DSA(仅签名)

第二个选项将仅创建一个密钥对。
这将仅用于数字签名。
因此,如果我们选择第二个选项,则可以在发送前对文档进行签名,但无法使用gpg对其进行加密(因为此选项不会创建用于加密的公共/私有密钥。
这只会创建publc /数字签名的私钥。

因此,如果我们选择此选项,gpg会通知我们该密钥对无法进行加密,作为密钥创建后的最后一条消息。
该消息如下所示。

Note that this key cannot be used for encryption.  You Jan want to use
the command "--edit-key" to generate a subkey for this purpose.

(3)RSA(仅签名)

第三种选择将通过使用另一种称为RSA的加密算法来生成数字签名密钥的功能相同。
与第二个选项类似,如果选择此选项,则将无法加密数据,但可以在发送之前对文档进行签名。

此选项将仅创建一个密钥对,类似于DSA(仅签名)选项。
因此,使用此选项创建签名密钥后,我们会收到类似的消息。

Note that this key cannot be used for encryption.  You Jan want to use
the command "--edit-key" to generate a subkey for this purpose.

有关GNUPG中的RSA,DSA和Elgamal的一些事实

  • DSA代表数字签名算法,仅用于对文档进行签名而不对其进行加密。
  • DSA基于称为离散对数问题的数学问题(即使强大的计算机也要解决这既困难又耗时的问题)
  • RSA算法也可以用于加密以及数字签名
  • 与RSA算法生成的大签名相比,DSA的签名大小较小。
  • RSA处理一个称为整数因式分解问题的数学问题(这也是计算机难以解决的问题)。
  • DSA在GPG中默认为1024键大小
  • 我们可以选择使用Elgamal算法加密的密钥大小,范围从1024到4096位
  • 私钥是解密和签名消息的主要组件,这意味着我们需要使用加密和密码保护来保护私钥,这由GPG默认完成
  • 设置私钥的到期日期是可取的,因为这样可以增加安全性。

现在,我们通过选择第一个选项来了解步骤,从而生成密钥对。
其中我们将选择第一个选项,因为我们需要在DSA算法的帮助下进行加密以及对数据/消息进行签名。

[root@myvm1 ~]# gpg --gen-key
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.
Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign only)
Your selection? 1
DSA keypair will have 1024 bits.
ELG-E keys Jan be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <[email protected]>"
Real name:
Name must be at least 5 characters long
Real name: theitroad
Email address: [email protected]
Comment: theitroad Key
You selected this USER-ID:
    "theitroad (theitroad Key) <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.++++++++++..+++++.+++++.+++++.+++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++.........................................>.+++++........<.+++++....................+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
+++++++++++++++.++++++++++..+++++.+++++...+++++..+++++.++++++++++++++++++++.+++++..+++++.+++++++++++++++++++++++++++++++++++.+++++..+++++++++++++++.+++++.++++++++++>+++++...+++++.>+++++...........................................>+++++...<.+++++>+++++.................+++++^^^
gpg: key 195C8BDB marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   1024D/195C8BDB 2013-04-26
      Key fingerprint = 5C77 CEE6 10B9 5E1C 1B0D  B2E1 BB1D E5D8 195C 8BDB
uid                  theitroad (theitroad Key) <[email protected]>
sub   2048g/8BCCF604 2013-04-26

在上面显示的gpg --gen-key命令示例中,我们已经讨论了DSA和Elgamal,DSA,RSA的第一个选择选项。

gpg询问的第二个问题是指定Elgamal密钥的位大小(将用于数据加密)。
人们普遍认为,如果我们使用长尺寸的钥匙,那么就很难在其上发生暴力行为。
但是,由于人类的粗心大意或者其他一些社会工程手段,会发生针对加密密钥的成功攻击。

尽管较长的密钥可以抵御暴力攻击,但它们本身在加密和解密数据时成为性能瓶颈。

要了解密钥大小的重要性,我们需要考虑攻击者成功进行破解所需的组合和尝试次数。
128位密钥意味着攻击者必须尝试2 128种组合。
密钥大小为1024意味着攻击者必须经过21024个组合才能找到正确的匹配项。

在此处选择默认的1024即可。

下一个选项是指定天数,在此天之后私钥将过期。
大多数人都忽略了这一点,然后按Enter键以选择默认的“ 0”选项,该选项不会使密钥失效。

下一个选项将要求我们提供一些身份信息,这些信息将唯一地标识此密钥。
询问的信息将是电子邮件,名称和注释。
稍后,我们可以选择任何信息以标识所需的密钥。
这非常有用,因为我们将能够管理多个密钥,并且可以在提供的一个标识信息的帮助下使用所需的密钥。

gpg最终要求提供一个密码,该密码将用于通过加密的安全性保护私钥。
如果要使用此私钥进行加密,系统将提示我们输入密码。

gnupg中的加密,导入和导出密钥,签名和验证示例

我们已经为加密/解密和数字签名创建了密钥对。
现在,让我们通过一些真实的例子来了解整个过程是如何工作的。

首先,我们通过一些示例签名创建来了解gnupg中的数字签名是如何工作的。

数字签名是在私钥的帮助下完成的,并且可以在相应的公钥的帮助下进行验证。
这是有可能的,因为公钥将通过电子邮件或者分发给所有收件人。
数字签名不会加密数据,但是会添加带有我们要签名的数据的哈希值的签名。
然后,接收者可以借助GPG或者任何其他此类应用软件来验证签名。

首先,我们创建一些消息并对其进行签名,以便接收者可以验证我们发送的消息。
假设我有一条最初以简单文本格式编写的消息。

[root@myvm1 ~]# cat example-message
hello this is a test message to verify gpg signature. This message is from theitroad.com team, hence it is signed with our private key, which you can verify with our public key.
[root@myvm1 ~]#

现在,让我们用gpg签名该消息。

[root@myvm1 ~]# gpg --local-user "theitroad" --clearsign "example-message"
You need a passphrase to unlock the secret key for
user: "theitroad (theitroad Key) <[email protected]>"
1024-bit DSA key, ID 195C8BDB, created 2013-04-26

在上面显示的示例方法中,我们在生成密钥对时使用了我们提交的“ Realname”参数(在本例中为“ theitroad”)。
如果我们查看gpg的手册页,就会知道--clearsign,参数用于制作纯文本格式的签名,可以在任何文本编辑器的帮助下进行查看。

签名消息将提示我们输入密码,这是我们用来加密私钥的密码。
由于私钥是用于签名消息的私钥,因此需要提供密码。

现在,我们已经签名了消息,现在让我们看看签名的样子。
对文本消息签名后,我们将获得一个扩展名为.asc的文件,其中将同时包含消息和签名。
让我们看一下包含数字签名的example-message.asc文件。

[root@myvm1 ~]# cat example-message.asc
-----BEGIN PGP SIGNED MESSAGE----
Hash: SHA1
hello this is a test message to verify gpg signature. This message is from theitroad.com team, hence it is signed with our private key, which you can verify with our public key.
-----BEGIN PGP SIGNATURE----
Version: GnuPG v1.4.5 (GNU/Linux)
iD8DBQFRe2R1ux3l2Blci9sRAtd8AKCM6sN4Xg3aWLyOAiUza5HurxUU8gCfVlbw
wxI9ZZ2VnCY88SBR/e/xkfo=
=vBz9
-----END PGP SIGNATURE----
[root@myvm1 ~]#

输出清楚地提到,我们签名的消息的哈希值是使用SHA1的。

现在,正如我前面提到的,需要验证我们签名的消息的人将需要公共密钥。
为此,我们需要发布公共密钥,并将其提供给收件人。
这可以通过电子邮件发送给首选收件人来完成,也可以在上下载。
但是为此,我们首先需要以简单的文本格式导出公共密钥,以便其他人可以使用它。
让我们看看如何。

[root@myvm1 ~]# gpg --armor --output "theitroad-public-key" --export "theitroad"

在上面显示的示例中,我们已将公钥导出到名为“ theitroad-public-key”的文件,该文件现在可供接收者使用。
在上面显示的命令中,我们在gpg命令中使用了--armor选项,以指定输出必须为纯文本格式。
--export参数需要密钥的身份,这也是我们在生成密钥对时使用的实名(我们也可以在创建密钥环时使用提供的电子邮件地址)。
现在,让我们看看我们的公共密钥的内容。

[root@myvm1 ~]# cat theitroad-public-key
-----BEGIN PGP PUBLIC KEY BLOCK----
Version: GnuPG v1.4.5 (GNU/Linux)
mQGiBFF6nikRBACEHpnImkcocXCigGgG9CqJYJTXT+X/3Ky1nLgXmhJf1O/Lk7pA
mfO0TdPC4A/RkKZf0jHm1kkIl4EE02t4c+/qts1z1LOxDoHTDjx+xpfRpC2ekKq5
2+LtSXaFRlbTPVsi4cSEBDOGUpyAFOYAjtKI1c+q90Ru1g7ViXduXtbVfwCgpFxV
ZbFAmTpK47xKcqnpwwWv9ysD/j3w34vS7sywgAuflVecYeYa1xGM1XLPfZDMJKJO
AxwuJBrsx6GX3jKh6ah1MlnbxB1+rqzWqKa+qeVHGTegQV89GcC1ut06EcJamd4l
k2LG2MdkvKVoQBGQIj+VglP24Q9KfhhBd7mheqzLsQh2i5YtW6TTszvG/i283V6R
lSAMA/4r9lpwTL1Fgsgb8794PkaxKL6JwRgRWoIwCikRKB9W2Ot+/nK0y2nfZcpX
5jzw0R40jE+AMItL25ulRPpqHVD9CHxBPgOH0lwTg3Tk5KcFsgn1pxch+3K/TuDM
OXJN64V35AIEayUHNIT+42Hym1xalX1vGZMO+x7F5/wrUyNGIrQuU2xhc2hyb290
IChTbGFzaHJvb3QgS2V5KSA8YWRtaW5Ac2xhc2hyb290LmluPohgBBMRAgAgBQJR
ep4pAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQux3l2Blci9s6fACfVsbb
J8xNQ8DMB3eJl1QVFypTaGgAmgNA/Gnh0UwR83GVezWkBGmqmI6BuQINBFF6njUQ
CAChBVGhNI5lKcQ0le94ABom5RTu2bCPnE0E5jijauANBGqvocae93yTUAu98Mdy
r3587m8Zpx1Pv2FH/PSGs3cHWcugCJcH9yfxiXRy9rCvQu8NYFdwVFrInNpgt4nT
7JPUDYEqpvYLBfjxpbPCrbcUGr9ZwFm2sNjIiZBhWzm9bzcEIp9JxwxWoHSXc0rD
AxZMfdUY1OvGNjfpbIewNm2QhJ0CwvSX4j0FoSpkbx0Axnmuf/W+CXgI3VJir9hd
RRgGpligi11xQsOhWtBSesLDP7ooecsIRPr6cTlQz73FErY5u+P6xmyxfuKT4Hfx
xFFoP9DGNpoJFhbOkJCvhxpjAAMFCACWLKq+O2PnXY29jS8gf3LhLD62agSKuw3f
GxhRx3M1ZWcwsG05IrXaS1YUZ1JlFmxgF3nSzZc11mbZHxJB+2IDje93MlwT9Kw5
7h8f2khGAXg1qg43Amel11WdfptWd+ULBxM4iPTC1xub4PAP/iUF2L/c7vFlvCIZ
gAkgY8dXC+ElNKV56vKCLl3+5REvjK6NI38wC104ONdPTemyPK+wRNBrTSNS6+ao
BOrKoNGEveeU0sDo1H59hp3k5m+JvNdW1IMfj2VVxzaNGmm+BbdbUUShEZDlkbTo
bNuKEUfGTmuepJFwWzxrEeBkrxlhFnyJTF2vw0F1oEZgmHnOmDq1iEkEGBECAAkF
AlF6njUCGwwACgkQux3l2Blci9vMSACfWDx1EshJtDLh3zD3IaZ+xEyGAfwAnjD9
sS7kecpFm5niggNSyjzD2+KK
=fc8Y
-----END PGP PUBLIC KEY BLOCK----
[root@myvm1 ~]#

拥有此公共密钥的任何收件人都可以将其导入到他的公共密钥列表中,以在将来验证我们的签名消息。
让我们看看如何导入这个公钥。

[sarath@myvm1 ~]$gpg --import theitroad-public-key
gpg: keyring `/home/sarath/.gnupg/secring.gpg' created
gpg: key 195C8BDB: public key "theitroad (theitroad Key) <[email protected]>" imported
gpg: Total number processed: 1
gpg:               imported: 1
[sarath@myvm1 ~]$

gpg中的--import选项将我们要导入的公钥作为参数,并将具有真实姓名和电子邮件地址等的确切身份。
我们还可以使用同一密钥标识来验证签名和加密消息。

让我们看看如何使用我们刚刚导入的这个公共密钥来验证消息。
在这里显示此示例,我们将验证先前签名的消息example-message.asc。

但是,在我们使用新导入的密钥验证任何消息之前,我们需要对该密钥设置信任级别。
否则,gpg会向我们显示如下警告消息。

gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

为了在公共密钥上设置信任级别,我们需要使用参数--edit-key。

[sarath@myvm1 ~]$gpg --edit-key "theitroad"
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

pub  1024D/195C8BDB  created: 2013-04-26  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048g/8BCCF604  created: 2013-04-26  expires: never       usage: E
[ unknown] (1). theitroad (theitroad Key) <[email protected]>
Command> trust

带gpg命令的--edit-key参数会提示我们,我们可以其中为该公钥分配信任级别。
在gpg编辑提示中,我们需要输入命令trust来为该公钥分配信任级别。
我们将获得5个不同级别的信任,我们将从中选择5个级别以完全信任密钥。

1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

选择信任级别后,我们可以通过键入“退出”退出此密钥编辑提示。
现在,让我们最后借助我们已导入的此受信任的公钥来验证签名。

[sarath@myvm1 ~]$gpg --verify example-message.asc
gpg: Signature made Fri 26 Apr 2013 10:39:01 PM PDT using DSA key ID 195C8BDB
gpg: Good signature from "theitroad (theitroad Key) <[email protected]>"
[sarath@myvm1 ~]$

最后,让我们在已导入的theitroad公钥的帮助下发送一些加密的消息,然后尝试在收件人的私钥的帮助下对其进行解密。

为了在gpg的帮助下加密消息,我们需要设置两个命令行参数。
一个参数将指定要使用的公共密钥(这是通过--recipient参数完成的,因为数据将使用收件人的公共密钥进行加密。
),另一个参数将获取使用此公共密钥加密的文件。

为了加密邮件到theitroad,我们将使用已经导入的theitroad公钥。

[sarath@myvm1 ~]$gpg --recipient "theitroad" --output "sample-message.gpg" --encrypt "sample-message"

现在,可以通过任何方法将此输出文件发送给收件人。
收到邮件(sample-message.gpg)后,收件人可以使用其私钥轻松解密它,以查看其中的内容。

再次,这将要求接收者键入其私钥的密码,因为私钥用于解密此消息。

[root@myvm1 ~]# gpg --decrypt "sample-message.gpg"
You need a passphrase to unlock the secret key for
user: "theitroad (theitroad Key) <[email protected]>"
2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 (main key ID 195C8BDB)
gpg: encrypted with 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26
      "theitroad (theitroad Key) <[email protected]>"
hello this a sample message to test gpg encryption.

如何使用纯文本发送带有gpg的加密电子邮件?

在上面显示的将加密数据发送到接收方的方法中,我们需要发送整个文件。
主要原因是因为加密文件为二进制格式。

如果我们想将完整的电子邮件作为简单文本发送,但仍然加密,该怎么办。
为此,我们需要使用相同的--armor选项,我们之前在导出或者使公钥以纯文本形式可用时使用了该选项。

因此,第一步是在文本编辑器中键入整个电子邮件。
让我们看一下这个示例电子邮件。

[sarath@myvm1 ~]$cat sample-email
Hi,
This is a test email message to test encryption..
Thanks & regards
[sarath@myvm1 ~]$

现在,使用收件人的公共密钥(在我们的情况下为“ theitroad”)对整个电子邮件进行加密。

[sarath@myvm1 ~]$gpg --armor --recipient "theitroad" --output "sample-email.asc" --encrypt "sample-email"
[sarath@myvm1 ~]$

下一步是简单地将“ sample-email.asc”的内容复制粘贴到电子邮件正文中(来自任何电子邮件客户端,如thunderbird,outlook甚至gmail等)。

收件人可以简单地通过以下方法将电子邮件内容粘贴粘贴到文本文件中,然后将其解密以读取消息。

[root@myvm1 ~]# gpg --decrypt "sample-email.asc"
You need a passphrase to unlock the secret key for
user: "theitroad (theitroad Key) <[email protected]>"
2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 (main key ID 195C8BDB)
gpg: encrypted with 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26
      "theitroad (theitroad Key) <[email protected]>"
Hi,
This is a test email message to test encryption..
Thanks & regards
[root@myvm1 ~]#

再次,将提示接收者输入其私钥的密码。
在上面显示的示例中,我们假设收件人已将电子邮件内容保存到名为“ sample-email.asc”的文件中。
接收者用来保存内容的文件名根本没有关系。