在Linux中使用GPG公钥加密,解密,签名文件

时间:2020-02-23 14:40:37  来源:igfitidea点击:

安全是任何不能与其他机器和用户完全隔离的系统的基础的重要组成部分。
在本文中,我将指导我们完成在将文件传输到客户端之前保护关键数据的步骤。
我们可以在将文件传输或者发送给收件人之前,使用签名的GPG密钥对文件进行加密。
客户端收到文件后,他们可以在查看内容之前进一步解密文件。
这样,可以确保机密文件不受任何黑客窃取数据的攻击。

什么是加密?

安全的基石之一是加密,它提供了一种加扰数据以安全传输给其他方的方法。
用加密术语来说,要加密的数据或者消息称为纯文本,而生成的加密文本块称为密文。
存在使用密钥将明文转换为密文的过程,这些密钥本质上是用于锁定和解锁数据的指定长度的随机数。
通过根据一组称为加密算法的数学指令将密钥应用于明文来实现此转换。

GPG加密和解密如何工作?

GPG使用公共密钥加密,其中我们创建一个密钥对:一个私有或者秘密密钥由我们自己保留,一个公共密钥与通讯员或者全世界共享。
此两键系统的重要部分是,通过拥有另一个键就无法计算出任何一个键。
它们每个都是系统的独立且必要的部分,并基于扎实的数学基础。

此设置使我们可以

  • 使用私钥对文档签名,以为具有公钥的收件人提供标识和消息完整性。

  • 身份证明意味着收件人可以确定该文件来自我们。

  • 邮件完整性意味着收件人知道邮件尚未更改。

  • 我们可以提供这些功能,因为只有我们自己的私钥。

  • 使用收件人的公共密钥来加密文档并提供保密性。

  • 保密意味着只有收件人(具有相应的私钥)才能解密文档。

  • 组合这些步骤以提供标识,消息完整性和保密性(即,只有收件人可以解密文档,收件人知道文档来自我们,并且收件人知道文档没有被更改)。

创建一个GPG密钥对

要开始使用GPG,我们需要为自己创建一个密钥对。

  • 将gpg与--gen-key方法一起使用来创建密钥对。

  • 使用此选项,gpg将创建并填充~/.gnupg目录(如果不存在)。

  • secring.gpg文件是保存秘密密钥的keyring

  • pubring.gpg文件是保存公钥的keyring

以下步骤显示了hynman为自己创建密钥对。

[root@node1 ~]# gpg --gen-key
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created

第一个问题是关于要使用哪种加密("哪种密钥")。
默认的RSA和RSA是一个不错的选择。

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1

下一个问题涉及密钥的大小。
较大的密钥更安全,但处理时间更长。
2,048位长的密钥是一个很好的折衷方案。

RSA keys Jan be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits

我们对下一个问题的答案确定密钥何时或者是否将失效。
对于大多数用途,不过期的密钥是一个不错的选择。
我们必须通过输入y确认此选择。

Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

接下来,我们指定真实姓名(我们可以在评论部分中指定昵称或者名称),电子邮件地址(大多数人与我们联系的人)和可选评论。
指定这些特征后,将出现提示,供我们编辑,退出或者继续(确定)。

GnuPG needs to construct a user ID to identify your key.
Real name: hynman Prasad
Email address: [email protected]
Comment: hynman Prasad's Inbox
You selected this USER-ID:
    "hynman Prasad (hynman Prasad's Inbox) <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

生成密钥对的最后一步是指定密码,以确保秘密密钥安全。
密码短语应具有" hynman"特征作为密码,但应更长。
就像输入密码一样,保护密码短语。

You need a Passphrase to protect your secret key.
            lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
            x Enter passphrase                                    x
            x                                                     x
            x                                                     x
            x Passphrase ** ****__________________________________ x
            x                                                     x
            x                                                     x
            mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
            lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
            x Please re-enter this passphrase                     x
            x                                                     x
            x Passphrase ** ****__________________________________ x
            x                                                     x
            x                                                     x
            mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

输入密码后,gpg会生成密钥。
生成真正的随机密钥需要许多随机字节,而生成随机字节则需要熵。
如说明所示,键入键盘,移动鼠标,然后使用磁盘(例如,复制多个大文件)来获取熵。

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: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 20B43A0C 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   2048R/20B43A0C 2016-12-09
      Key fingerprint = FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C
uid                  hynman Prasad (hynman Prasad's Inbox) <[email protected]>
sub   2048R/3832437D 2016-12-09

gpg完成后,就生成了密钥对。
gpg实用程序将所有信息存储在~/.gpg目录中。
密钥和使用gpg导入的公共密钥都存储在密钥环中。
输出显示了使用gpg时将使用的两项:密钥ID(示例中为20B43A0C)和密钥指纹。

生成密钥对后,可以使用gpg --list-keys和--fingerprint`选项显示有关密钥对的信息。
指纹是密钥公开部分的简写。
我们可以将其用于手动识别密钥。

[root@node1 ~]# gpg --list-keys
/root/.gnupg/pubring.gpg
-----------------------
pub   2048R/20B43A0C 2016-12-09
uid                  hynman Prasad (hynman Prasad's Inbox) <[email protected]>
sub   2048R/3832437D 2016-12-09
[root@node1 ~]# gpg --fingerprint
/root/.gnupg/pubring.gpg
-----------------------
pub   2048R/20B43A0C 2016-12-09
      Key fingerprint = FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C
uid                  hynman Prasad (hynman Prasad's Inbox) <[email protected]>
sub   2048R/3832437D 2016-12-09

导出和导入公共密钥

接下来,我们需要导出公共密钥,然后将公共密钥共享给收件人。
下面的命令以ASCII格式(--armor;或者-a)将公共密钥(--export)导出到名为hynman_pgp.asc(--output;或者-o)的文件中。
然后是我们要写入的文件的名称)。
如果指定用户,则该命令将导出该用户的公钥,否则将导出" keyring"上所有用户的公钥。

接下来," hynman"将其公共密钥写入" hynman_pgp.asc",然后显示该文件。

[root@node1 ~]# gpg --export --armor --output hynman_pgp.asc [email protected]
[root@node1 ~]# cat hynman_pgp.asc
-----BEGIN PGP PUBLIC KEY BLOCK----
Version: GnuPG v2.0.22 (GNU/Linux)
mQENBFwNHRQBCAC0W1wyPH/d8H/2j55V3isHxIOg7jBlqZ2AUNZtH2errDSQWKEX
jgx7jA80Gn+/GpLMqga44Yhivb4hLiuys4J5tLid+9KOjJK4R67XB9iowW4XpkXm
HOpevLvW5O+pZlqBVOeswR8YUKb4DXqXsr8ebhvtI1xHvHeTUxWfH0ZJh3e4NtA7
X6PieG8u/2+Sl6yzcsAtj3MLyHIa8HJDnS8Nn49AJAWt8Is2Ln5ZMUpHGISlbWkS
PLWhwP2WwATFZ/0vtLG+lBlJkJ/UrmEXAuu56QBMYzMMxTWk1wnfpQweQC+1AcgN
..
AQABiQEfBBgBAgAJBQJcDR0UAhsMAAoJEFa+4u0gtDoMZiUH/2m0zTrauSCjHgC8
lx5W4hFzmgYnfAyJHyWj9A8lRvz6RlzZnjnvol76JJoALqvPKcgnsWiqkvybnqoZ
uR5FwDtPqDiyxAKCSAtVGAlRp5AD7pdclEh7vw/oGAT7vuq/TocesGFDWFqjyFrq
3bfYNNI0L5X0iE37AE6Kv7gQMsbfpwiUONz4zLDTexl+Ft6qGmu0bdSU5sTtt5Pm
VxDtZDdoCWBXCrEHrzUkv74RqXfYK5m+/Tj/Bbt6hHLH6in9Z4Zvh4c4wbGFNg8t
1maOnDOpB57jvax/oMhRFp7NR7H84NTmi+jqJR0882H4YmNpWwv3ndyFzP4w9xm3
0EFKdf8=
=bzPI
-----END PGP PUBLIC KEY BLOCK----

接下来,hynman将使用scp导出的公钥发送到Amit

Amit收到hynman'的公钥后,他使用以下命令将其添加到他的keyring`中

[root@node2 ~]# gpg --import hynman_pgp.asc
gpg: key 20B43A0C: public key "hynman Prasad (hynman Prasad's Inbox) <[email protected]>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

重要的提示:

接下来," hynman"按照相同的步骤将" Amit"的公钥添加到他的" keyring"中。
以下示例假定" hynman"和" Amit"在其"密钥环"上具有彼此的公钥。

以下是在node2上重复执行针对" Amit"的过程之后,在node1(Deepeep)和node2(Amit)上的键的列表。

[root@node1 ~]# gpg --list-keys
/root/.gnupg/pubring.gpg
-----------------------
pub   2048R/20B43A0C 2016-12-09
uid                  hynman Prasad (hynman Prasad's Inbox) <[email protected]>
sub   2048R/3832437D 2016-12-09
pub   2048R/613099BE 2016-12-09
uid                  Amit Kumar (Amit Kumar's Inbox) <[email protected]>
sub   2048R/B8AE9Nov 2016-12-09
[root@node2 ~]# gpg --list-keys
/root/.gnupg/pubring.gpg
-----------------------
pub   2048R/613099BE 2016-12-09
uid                  Amit Kumar (Amit Kumar's Inbox) <[email protected]>
sub   2048R/B8AE9Nov 2016-12-09
pub   2048R/20B43A0C 2016-12-09
uid                  hynman Prasad (hynman Prasad's Inbox) <[email protected]>
sub   2048R/3832437D 2016-12-09

签署公钥

如果我们相信公钥属于它所说的人,则可以对该公钥进行签名以使其更值得信赖。
签署密钥的人越多,密钥就越值得信赖。

密钥ID标识密钥。
我们可以使用gpg --list-key选项列出keyring上所有密钥的ID。
以下输出显示" Amit"的密钥长2,048位,使用RSA加密(R),并且在" node1"上具有密钥ID" 613099BE"。

[root@node1 ~]# gpg --sign-key 613099BE
pub  2048R/613099BE  created: 2016-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048R/B8AE9Nov  created: 2016-12-09  expires: never       usage: E
[ unknown] (1). Amit Kumar (Amit Kumar's Inbox) <[email protected]>

pub  2048R/613099BE  created: 2016-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: 8D09 5E6D 57BF 81AF D356  3190 FD29 32DC 6130 99BE
     Amit Kumar (Amit Kumar's Inbox) <[email protected]>
Are you sure that you want to sign this key with your
key "hynman Prasad (hynman Prasad's Inbox) <[email protected]>" (20B43A0C)
Really sign? (y/N) y
You need a passphrase to unlock the secret key for
user: "hynman Prasad (hynman Prasad's Inbox) <[email protected]>"
2048-bit RSA key, ID 20B43A0C, created 2016-12-09

以下输出显示" hynman"的密钥长2,048位,使用RSA加密(R),并且在" node2"上的密钥ID为" 20B43A0C"。

[root@node2 ~]# gpg --sign-key 20B43A0C
pub  2048R/20B43A0C  created: 2016-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048R/3832437D  created: 2016-12-09  expires: never       usage: E
[ unknown] (1). hynman Prasad (hynman Prasad's Inbox) <[email protected]>

pub  2048R/20B43A0C  created: 2016-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C
     hynman Prasad (hynman Prasad's Inbox) <[email protected]>
Are you sure that you want to sign this key with your
key "Amit Kumar (Amit Kumar's Inbox) <[email protected]>" (613099BE)
Really sign? (y/N) y
You need a passphrase to unlock the secret key for
user: "Amit Kumar (Amit Kumar's Inbox) <[email protected]>"
2048-bit RSA key, ID 613099BE, created 2016-12-09

加密和解密文件

使用公用密钥加密文件时,只有相应的专用密钥才能解密该文件。
如果我们想将文件发送给某人,使得只有该人可以阅读(或者运行)该文件,则可以使用收件人的公钥对该文件进行加密。
然后,收件人可以使用她的私钥解密文件;没有其他人可以读取该文件。

我在node1上有一个秘密文件

[root@node1 ~]# cat secret
This is a secret file

接下来," Amit"使用" hynman"的公钥对机密文件进行加密,生成一个名为" secret.gpg"的不可读文件。

[root@node1 ~]# gpg --recipient [email protected] --encrypt secret
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1  valid:   1  signed:   0  trust: 1-, 0q, 0n, 0m, 0f, 0u

然后将文件发送到node2上的Amit

[root@node1 ~]# scp secret.gpg node2:~/
root@node2's password:
secret.gpg

hynman收到文件时,他使用自己的密钥对其进行解密:

[root@node2 ~]# gpg --output secret --decrypt secret.gpg
You need a passphrase to unlock the secret key for
user: "Amit Kumar (Amit Kumar's Inbox) <[email protected]>"
2048-bit RSA key, ID B8AE9FEB, created 2016-12-09 (main key ID 613099BE)
gpg: encrypted with 2048-bit RSA key, ID B8AE9FEB, created 2016-12-09
      "Amit Kumar (Amit Kumar's Inbox) <[email protected]>"

接下来,将创建一个解密文件" secret",现在" Amit"可以查看文件的内容。

[root@node2 ~]# cat secret
This is a secret file