the Usage of GPG

什么是加密?
Bob 想给 Alice 发条消息,但是担心消息被其他人获取,于是他使用 Alice 给他的公钥进
行加密,将密文发给 Alice 后,Alice 用她对应的私钥来解密。这就是非对称加密与解密(公开密钥加密算法)。加密可以防止信息泄露。

什么是签名?
Alice 收到了 Bob 给她发的一条消息,但是她不确实一定就是 Bob 发的。于是 Bob 用他生成的私钥对这条消息进行数字签名,Alice 收到签名后的消息与公钥后,用这把公钥来验证。这就是数字签名与验证。签名可以防止信息篡改以及伪造。


密钥的产生以及查看

密钥对的产生
$ gpg –gen-key

查看公钥
$ gpg -k

查看私钥
$ gpg -K

密钥的导出

$ gpg -a [-o key.pub] –export keyID

或者

$ gpg -a –export -a keyID [> key.pub]

我们还可以选择上传至密钥服务器来传播密钥
$ gpg –keyserver keyserver.ubuntu.com –send-keys keyID

私钥的导出
$ gpg -a –export-secret-key keyID [> key.sec]

密钥的导入

$ gpg –-import key.pub

或者从密钥服务器来导入公钥
$ gpg –keyserver keyserver.ubuntu.com –recv.keys keyID

通过次条命令来搜索你要导入的公钥的信息
$ gpg –keyserver keyserver.ubuntu.com –search-keys keyID/username/email

私钥的导入,这个应用的场合比较少,做物理迁移时可能会用到
$ gpg –allow-secret-key-import keyID/username/email

密钥的刪除

首先删除私钥
$ gpg –delete-secret-key keyID

再删除公钥
$ gpg –delete-key keyID

加密解密

非对称加密

使用公钥加密
$ gpg -[a]e [-r jaseywang] [-o filename.gpg] filename
-e:加密
-a:使用 ASCII 形式输出,否则为二进制乱码
-r:选择公钥的发放者
-o:输出

解密
$ gpg -d -o filename filename.gpg

对称加密

默认使用 CAST5 加密
$ gpg –symmetric/-c  filename

解密
$ gpg -d filename.gpg

如果你的私钥不幸泄露了或者丢失了,做一个公钥回收的证书来声明公钥不再有效。在你产生钥匙对的时候就产生一份取消钥匙证书是一种明智的做法。如果你这样做的话,一定要把证书保存好!

产生密钥回收证书
$ gpg -o revoke.asc –gen-revoke keyID

导入,声明作废
$ gpg –import revoke.asc

或者发送至服务器,声明作废
$ gpg –keyserver keyserver.ubuntu.com –send keyID

这里就出现了一个问题,因为公钥每个人都可以获取的到,那么 Alice 如何确认收到的消息就一定是 Bob 发送的了?这里就涉及到数字签名的问题。

签名

生成签名
$ gpg –sign/-s [-a][-o file.gpg] file                        

主要用于文本,签名时将签名信息附在文本内容的后面,验证时只要把该文件做参数就行了
$ gpg –clearsign file

生成单独的签名文件
$ gpg –detach-sign/-b [-a] file

验证

$ gpg –verify file.gpg                                             

下面的例子都是由 kiki 这台主机将消息发往 jasey 这台主机,kiki 和 jasey 这里指的仅仅是主机的名称或者说是 ip。实际的 user 是两个 root。分别描述加密解密,签名验证的过程。

加密/解密

@jasey

生成密钥对,生成过程中会让你填写相应的信息
# gpg –gen-key

查看公钥信息
# gpg -k

将公钥以 ASCII 的形式导出
# gpg –export -a -o jasey.pub [email protected]

查看文件格式
# file jasey.pub
\jasey.pub: PGP armored data public key block

将通过相对安全的方式将 jasey 的公钥传送给 kiki
# scp jasey.pub [email protected]_ip:

@kiki

查看文件
# ll jasey.pub

将 jasey 产生的公钥导入
# gpg –import jasey.pub

怎知道所导入公匙是 jasey 的 ? gpg 要你承诺并使用 gpg –sign-key name 对这个公钥进行签名,来告诉 gpg 你能够确认公钥是正确的:
# gpg –sign-key jasey

查看 jasey 的信息
# gpg -k jasey

创建一个要加密的文件
# echo hello > kiki

加密 kiki 这个文件,成为 kiki.asc
# gpg -ae -r jasey [-o kiki.asc] kiki

获取文件的类型
# file kiki*
kiki:     ASCII text
kiki.asc: PGP message

现在可以将 kiki.asc 通过比较安全的方式发送给 jasey 了
# scp kiki.asc [email protected]_ip:

@jasey

输入 jasey 密码,解密
# gpg -d [-o kiki] kiki.asc

生成原文件
# cat kiki
hello

比较文件内容一致没有差异
# ssh [email protected]_ip cat ~/kiki | diff ./kiki –
[email protected]_ip's password:
#

上述就是一轮完整的公钥加密全过程。下面演示的是利用公钥体系来实现数字签名与验证。依然以 kiki 发送消息给 jasey 为例。

签名/验证

@kiki

生成密钥对
# gpg –gen-key

创建要签名的文件
# echo hello > kiki-sign

用 kiki 的私钥签名
# gpg –sign -a kiki-sign

查看文件类型
# file kiki-sign*
kiki-sign:     ASCII text
kiki-sign.asc: PGP message

将 kiki 的公钥导出
# gpg –export -a -o kiki.pub

将 kiki 的公钥,原文件以及经过签名的文件传送给 jasey
# scp kiki.pub  kiki-sign kiki-sign.asc [email protected]_ip:

@jasey

将 kiki 的公钥导入
# gpg –import kiki.pub

验证,签名成功:“Good signature”
# gpg –verify kiki-sign.asc
gpg: Signature made Thu 31 Mar 2011 10:14:10 AM EDT using RSA key ID 2E66C69C
gpg: Good signature from "panda <[email protected]>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 4905 2529 9903 AF35 8744  2812 E912 8433 2E66 C69C

但我们发现在 “Good signature” 下面又多了几行字,大致意思就是说我们不能确定 kiki 这把公钥就一定是 kiki 的。尽管我们上例中通过 ssh 这个相对安全的隧道来传输公钥,但是系统依然不能肯定 jasey 拿到的公钥就一定是 kiki 生成的那个公钥,所以我们此时可以通过诸如物理手段将这把公钥传送给 jasey,然后将 kiki 的这把公钥加入到 trustdb:

# gpg –update-trustdb –trusted-key LONG-KEYID

那个 LONG-KEYID 可以这样得到,以 pub 开头的最长的那个字段就是 LONG-KEYID 了:

# gpg –with-colons -k

这几步做好了再 verify 的时候就不会出现上述的 WARDING 了。

还有一种用于文本的签名,它将签名的信息直接附在文本的最后,此时验证只要 kiki.asc 这个文件:

# gpg –clearsign -a kiki

最后还有一种签名,可以对文件进行独立的分离式签名,这种签名一般用于公共场合,它只关注信息是否被篡改,而不关注信息是否被泄露。这时候就需要 kiki 和 kiki.asc 两个文件:

# gpg –detach-sign -a kiki

最后一种情形的应用场合很多,在大多数的开源软件项目下载页面会有 gpg 的签名验证。常见的比如 apache,mysql(via 1,2),TorOpenSSL动态网等等。

前些天 Mysql 被攻击了,我现在(2011  年3  月31 日 )下载他源码进行签名时,会出现如下信息:

# gpg –verify MySQL-5.5.10-1.linux2.6.src.rpm.asc MySQL-5.5.10-1.linux2.6.src.rpm
gpg: Signature made Mon 14 Mar 2011 05:32:22 PM EDT using DSA key ID 5072E1F5
gpg: BAD signature from "MySQL Package signing key (www.mysql.com) <[email protected]>"

显然是遭到破坏了。其他的诸如摘要(MD5 等)也可以防止信息篡改。

在现实应用中,用的最多的应该就是即加密又签名:加密防止信息泄露而签名防止信息篡改及伪造。
# gpg -r jasey  -s -e kiki

 
参考:
http://www.gnupg.org/
  • http://www.zypatroon.com zypatroon

    表示前面两段还是不够浅显易懂啊~ 建议加实例~

    • http://jaseywang.info jaseywang

      妹子啊,这个是写给有一定基础的同学看的 ^_<

      • http://www.zypatroon.com zypatroon

        什么是加密什么是解密都说不清. 有基础也给你弄糊涂了.

        如果我有一段信息”小猪”, 比如说某人的加密是: “1234”, 定义一个运算 F[“infor”,”pubs”] 生成的信息段寄给某人, 然后某人在用一个运算解开?

        区别在于[加密]和[运算]哪个是公开的?

        如何确保不被破译? 毕竟公开了一个

        • http://jaseywang.info jaseywang

          密钥分为公钥跟私钥,他们俩是一一对应的关系。私钥只能有自己保管,公钥可以随意分发。发送人使用收件人的公钥通过非对称加密算法比如 RSA 进行加密,收件人使用私钥解密。即使被其他人截获了,由于他没有与公钥相对应的私钥,所以他无法解密。至于公钥的安全性等问题,这个是签名要做的。真正的生产环境要比上述的复杂的多。妹子,这样解释清楚么?

  • Pingback: My Understanding of Cryptography | Jasey Wang()

  • http://www.freetstar.com freetstar

    85%明白了…最近在这里学习了不少网络加密的东西,有意思