BLOG > 开源 > 使用GnuPG来加密/解密文件

使用GnuPG来加密/解密文件

最近想通过HTTP来传送备份的数据文件,但又担心被无耻之徒中途截获导致数据泄漏。于是就静下心来研究了一下GnuPG的使用。

以前也曾经了解过gpg签名的用途,但自己从来没有用过,在Google和gpg --help的帮助下,找了几篇文档,终于测试成功,把过程记下来,以免自己以后用脑过度导致中老年痴呆,记忆力下降,忘记了。

在两台主机间通过gpg加密传送信息,说的简单点,一般来说,就是在接收方的主机上生成一对密钥:一个公钥(public key),一个私钥(private key),然后将公钥(public key)发送给信息发送方,发送方使用这个公钥(public key)将信息加密编码(encrypt),然后将加密过的信息传送给接收方,最后接收方再利用自己的私钥(private key)将加密编码过的信息解码(decrypt)还原。在这个过程中,如果加密过的信息在传输过程中被第三方截取,则他们获取的信息只是加密过的乱码,如果他们没有私钥(private key),那就没有办法解码还原该信息(公钥是无法被用作解码的)。

下面就看看实际过程吧。我的接收端是Ubuntu Linux 9.04 (主机名atomsvr),发送端是FreeBSD 6.2(主机名monster)。

首先,在接收端运行GnuPG,使用 gpg --gen-key 命令生成密钥对(以下粗体文字是需要您输入的)。


wells@atomsvr:~$ gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 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.

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 may 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) 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) <heinrichh@duesseldorf.de>"

Real name: Wells Wang
Email address: wellswang@********.com
Comment:
You selected this USER-ID:
    "Wells Wang <wellswang@********.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

gpg: gpg-agent is not available in this session
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.
+++++..++++++++++..++++++++++++++++++++++++++++++.+++++.
+++++++++++++++++++++++++++++++++++++++++++++.+++++.+
+++++++++..+++++.+++++++++++++++>+++++.+++++..........+++++

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 271 more bytes)

这时候,主机需要一些随机数来生成密钥,所以你可以在这台主机上随便敲些其他命令,执行下别的应用程序,读写下磁盘,让操作系统生成足够多的随机数来满足密钥的生成。在这个例子中,我们选择了默认的DSA和Elgamal编解码算法,DSA的密钥(用于签名)长度1024,ELG-E密钥(用于解码)长度2048,密钥永不过期,你也可以根据自己的需求改变这些选择。在生成密钥的过程中,会让你输入一个Passphrase(密码短语)来保护私钥(private key),请牢记这个密码,在使用私钥来解密文件的过程中,需要用到这个密码。

完成后,我们可以通过 gpg -vk 命令来查看生成的密钥。

wells@atomsvr:~$ gpg -vk
/home/wells/.gnupg/pubring.gpg
------------------------------
pub   1024D/41532C13 2009-07-08
uid                  Wells Wang <wellswang@********.com>
sub   2048g/7A849913 2009-07-08

通过上面的命令我们可以看到生成的两个密钥,pub表示公钥,ID为41532C13。我们就是要把这个公钥导出,然后在要发送消息的服务器monster上导入使用该公钥加密信息。

下面,我们就使用gpg --armor --export 命令在atomsvr上导出公钥。

wells@atomsvr:~$ gpg --armor --export 41532C13 >backup.key
wells@atomsvr:~$
wells@atomsvr:~$ cat backup.key
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.9 (GNU/Linux)

mQGiBEpUuEwRBADJawj29f6y7r4Z+u98k40lzfn5Y0H3wiEWYZCnHMcZi4yqYfOC
deHaQrlbdEJ1V2R4BLqh32fqnjuAUYljtLj6k6icyUYF1URtVdgQGudmDIVcSkPl
4dbkoMyaaUCBbc8n6+UfppG4jRxMVas0PoHIy4Ntk4zD/sZ4RQs8zt76ewCgmcOK
czoMCLee15yIPPg+BYwfUvkD/0w6HXy5HpLNa290WerjtLqaac5nPFhQh/IwcEJw
OL3OQ5xx57BL1WULugTHQuPl2Vv+dWULsHCXNxdqL4jpZZ0JjpVZG9yJk20GndqW
Xy+SGvaAHgpL6SuUimpXxWf+x0LMY8q433FqSnkOWMAz/ICYm6kNxM2TTzwAvayv
i3EpA/oCTRQNpucrznxShJhAsYrYxoin904pZ+Iash3SExlIPk/IUqXR6iwAb71k
Kj0HhqxQpdfmaI61bJ/9MwUEZmTgWh07vvADmqb5PpyqsXFOqZYC0uM/SB9WGsV3
FdzBN19vh/EDiNtnkspSLhTxwCep7Fx7Iv84+CLjiYc6j9ZzLrQgV2VsbHMgV2Fu
ZyA8d2VsbHN3YW5nQG9zYWxsLmNvbT6IYAQTEQIAIAUCSlS4TAIbAwYLCQgHAwIE
FQIIAwQWAgMBAh4BAheAAAoJEBjRqcVBUywTWQgAniWYds4YNgbDOGX/tc4a1WrC
n2qHAJ4hvWEwSI/VXIVyAv9dclUbZ1HF8rkCDQRKVLhMEAgAlNwwyR5avmy9DHL4
GK40JJeL/tpryn8BPV/3ruIxkMivC/Zpj6FhxKwMjhp7BksH8BxA59qqZG2iojsl
FKG60IbyMy0ccjcG0UUPgRcg2FN6BFCwF3wpeiakcP/F2GaBHC5M2vz1BMW1GG+j
yaMwOGrci4Gjx29kkhB5e7YkznHXv9rbLTMNkF3UKu/C6IWlgAWt+tvKr8qy4l0g
xsLq4ttoBq0r/+vrsVgrr10FABi0NQD2fO1xolGXZDRJrulbhNg/WM6dQxwotRHp
fy82scniejYx06WeAYOeSRMyCAkEsbf5gD56ymqodifSm/VtG7tB4g0chxxm16fC
urSmzwADBQf+Jpj4jH28+sd+Ow5X/DpC8A9JLbsPDOkjGBv+tcN2Wtv9ZwdpUWd/
qVTfKYD8hhT2q2B5Tu0RBxyNLRCwS7tvFxjqFXnVJu0uLIMS8WFW63xLRGHCceQz
V4qALbHtyW+i1KYdXBD4qIVsp6Xyx0PlTArkJgyH5rDDQsBAFhAlONpwxbZglY1p
/C9PVfk2ywZhaK3K1p4bePvJhVpZiAYbDcUH5ilateGl4sX3cIul2U1KY+fWOB2d
RttHTMk++aAV57eKeta/hcFSTWYl97YVabf1Gosz7RY+sY3R26MWp1qy6HQIgo02
7yGqTbQskUfoLS5BgY68n6Bf61blF5wj8ohJBBgRAgAJBQJKVLhMAhsMAAoJEBjR
qcVBUywTbVkAoJiFA5OfaC5igDqqiOlFxuuTTxQVAJ9kq64oTeMVQbQ1SLcgKXl2
jeQyXA==
=Ptu/
-----END PGP PUBLIC KEY BLOCK-----

在上面的例子我们指定将ID为41532C13的导出到backup.key文件,然后查看该文件,可以看到,该文件内是一个长度为1024字节的密钥串。

接着,我们将这个backup.key文件用FTP或其他方法传送到要发送信息的monster服务器上,并使用gpg -import命令导入。

[wells@monster ~]$ gpg --import backup.key
Warning: using insecure memory!
gpg: keyring `/home/wells/.gnupg/secring.gpg' created
gpg: key 41532C13: public key "Wells Wang <wellswang@********.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

导入后,我们同样可以在这台服务器上使用gpg -vk命令来看一下导入的密钥。

[wells@monster ~]$ gpg -vk
Warning: using insecure memory!
gpg: using PGP trust model
/home/wells/.gnupg/pubring.gpg
------------------------------
pub   1024D/41532C13 2009-07-08
uid                  Wells Wang <wellswang@********.com>
sub   2048g/7A849913 2009-07-08

接着我们就可以用这个公钥来加密一个文本文件sylvan.sql。使用gpg -ea -r命令来加密。-ea是加密,-r是指定加密要使用的接收方的公钥的ID。

[wells@monster backup]$ gpg -ea -r 41532C13 sylvan.sql
Warning: using insecure memory!
gpg: 7A849913: There is no assurance this key belongs to the named user

pub  2048g/7A849913 2009-07-08 Wells Wang <wellswang@********.com>
 Primary key fingerprint: 88CF 12D6 7CB4 DBF9 DC3B  3312 18D1 A9C5 4153 2C13
      Subkey fingerprint: 57EE 4248 51C4 4FE7 400F  9318 0AEC FA41 7A84 9913

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y n
gpg: sylvan.sql: encryption failed: Unusable public key

不过出现了些意外,在加密时,系统认为我们刚才导入的公钥不受信任,因此发出了提示信息,要求确认该公钥是可信任的。这时候,输入y可以完成加密。但是我想要将该公钥状态更改为被信任,这样以后再使用加密命令就不必要每次都做确认了。

因此,在这台服务器上运行 gpg --edit-key 命令来编辑密钥状态。在编辑模式,使用trust命令来信任密钥。

[wells@monster backup]$ gpg --edit-key 41532C13
gpg (GnuPG) 2.0.11; Copyright (C) 2009 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.

Warning: using insecure memory!

pub  1024D/41532C13  created: 2009-07-08  expires: never       usage: SC  
                     trust: unknown       validity: unknown
sub  2048g/7A849913  created: 2009-07-08  expires: never       usage: E   
[ unknown] (1). Wells Wang <wellswang@********.com>

Command> trust
pub  1024D/41532C13  created: 2009-07-08  expires: never       usage: SC  
                     trust: unknown       validity: unknown
sub  2048g/7A849913  created: 2009-07-08  expires: never       usage: E   
[ unknown] (1). Wells Wang <wellswang@********.com>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  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

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  1024D/41532C13  created: 2009-07-08  expires: never       usage: SC  
                     trust: ultimate      validity: unknown
sub  2048g/7A849913  created: 2009-07-08  expires: never       usage: E   
[ unknown] (1). Wells Wang <wellswang@********.com>
Please note that the shown key validity is not necessarily correct
unless you restart the program.

Command> quit

在以上的例子中,我们可以看到,在trust之前,密钥的trust状态是Unkown,当我们选择 5 无限信任(trust ultimately)之后,密钥状态变为ultimate。

再次尝试加密文本文件sylvan.sql,这一回,我们就不需要确认是否信任公钥了。

[wells@monster backup]$ gpg -ea -r 41532C13 sylvan.sql
Warning: using insecure memory!
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

在加密完成后,会自动生成一个.asc文件 sylvan.sql.asc。该文件就是加密过后的文件,现在就可以把它传送给接收方服务器了。在传送的过程中,无需担心它会被第三方截获。因为即使第三方截获了该文件,他们没有私钥和保护私钥的密码短语,也只能看到类似这样的内容:

[wells@monster backup]$ more  sylvan.sql.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.11 (FreeBSD)

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

在接受方atomsvr服务器上收到这个加密后的文件sylvan.sql.asc后,就可以用gpg -o -d命令来使用注册过的私钥解密该文件了。-o参数指定了解密过后的文件名,-d参数指定了要被解密的文件名。

wells@atomsvr:~/backup$ gpg -o sylvan.sql -d sylvan.sql.asc

You need a passphrase to unlock the secret key for
user: "Wells Wang <wellswang@********.com>"
2048-bit ELG-E key, ID 7A849913, created 2009-07-08 (main key ID 41532C13)

gpg: gpg-agent is not available in this session
Enter passphrase:                   gpg: encrypted with 2048-bit ELG-E key, ID 7A849913, created 2009-07-08
      "Wells Wang <wellswang@*******.com>"

解密过程中系统会提示你输入保护私钥的密码短语(在生成密钥时输入的那个Passphrase),输入后,解密成功,生成了sylvan.sql文件。看一下,内容还原啦:

wells@atomsvr:~/backup$ more sylvan.sql
-- MySQL dump 10.9
--
-- Host: localhost    Database: sylvan
-- ------------------------------------------------------
-- Server version    4.1.21
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `adv_user_advertisements`
--

DROP TABLE IF EXISTS `adv_user_advertisements`;
CREATE TABLE `adv_user_advertisements` (
  `userid` int(10) unsigned NOT NULL default '0',
  `type` varchar(2) NOT NULL default '',
  `script` text NOT NULL,
  `description` varchar(255) NOT NULL default '',
  `desc_pos` enum('A1','A2','A3','B1','B2','B3') NOT NULL default 'A1',
  `isactive` enum('Y','N') NOT NULL default 'Y',
  PRIMARY KEY  (`userid`,`type`)
) TYPE=MyISAM;

--
-- Dumping data for table `adv_user_advertisements`
--

就这样,GnuPG用起来还是非常方便安全的。可以更进一步,写个脚本自动加密传输,用的时候再解密,这样就完美了。呵呵。

硬着头皮,申请了Quota,又写了篇技术的。主要是怕自己忘记……Sorry...

如果您喜欢这篇文章,您可以点击下列链接收藏
Del.icio.us Yahoo书签 365Key网摘 天极网摘 我摘 POCO网摘 YouNote网摘 和讯网摘 博啦网
发布时间 发布于 2009-07-15 21:53:02 | 阅读次数 阅读过833次 | 分类 开源 | 评论 没有评论