本文最近一次更新于 6 年 11 个月前,其中的内容很可能已经有所发展或是发生改变。
前言
我是一个很注重隐私的人,所以对密码学也就很感兴趣,这学期本着想进一步了解密码学的念头选了一门应用密码学的选修课(其实是为了混学分),虽说也没去过几次,但总想着这门课都快结束了总不能像没上过一样。这次借着 GnuPG(以下简称 GPG) 软件的使用也聊聊目前现代密码学中以密钥性质进行区分的两大加密方式。
对称密钥加密
大概半年前,写过一个暴力破解加密压缩文件的程序,说白了就是跑字典,不断的试密码,这只能破解常用密码,一旦用户采用随机生成的密码就无从下手。我们平时所用到的压缩加密大多都是对称性加密,即我们用同一字符串对文件进行加密,又用同一字符串进行解密(此时为了保证安全,密码需越复杂越好)。
明文 <–> 密钥 <–> 密文
对称加密很方便也很快速,但是也带来了一个很大的缺点,由于加密和解密用的都是同一密钥,在传输的过程中,要求双方取得相同的密钥,这会大大降低加密的安全性(注意:这里所说的不安全不是说对称加密算法不安全,而是从密钥的获取程度来说的,即密钥知道的人越少越安全)。
在如今的互联网时代,通信双方分隔异地且素为谋面,则对称加密要求事先交换共同密钥的安全性也无法得到保障。
公开密钥加密
那么为了解决对称加密的安全隐患,非对称加密诞生了。 与对称加密不同的是,非对称加密的加密和解密所需要的密钥是不同的,而且知道了其中一方,想推导出另一方(需要解决一个数学难题),在量子计算机时代来临之前,基本是不可能完成的。 因此公开其中一个密钥,并不会对密钥对的安全性有影响。 我们常说,公钥可以公开,私钥需要保密,但其实公钥和私钥在生成过程上,并无什么不同。并不是因为公钥公开后,解密出私钥困难,如果公开的是私钥,解密出公钥也同样困难。也就是说我们将一对密钥公开的那部分叫公钥,另一部分叫做私钥。并不是因为公钥,才能公开,私钥,就必须保密。
明文 <–> 公钥 <–> 密文 <–> 私钥 <–> 明文
前一段时间很火的勒索病毒就是采用的非对称加密中的 RSA-4096 加密算法。 想具体了解 RSA 加密原理的话,点击这里。 由于公钥加密在计算上相当复杂,导致其加密速度相对于对称加密来说慢。
数字签名
其中对称加密还有一个用处:数字签名。 对称加密的公钥和私钥在使用顺序上并没有什么要求,你可以用公钥加密,私钥解密,这就是非对称加密算法,同样可以用私钥加密,公钥解密,而这就成为数字签名。 由于私钥是发送者保存的,发送者用私钥加密后的信息,任何拥有该发送者的公钥的人都可以解密该信息。如果接收用发送者公开的公钥解开了,那么说明这个信息是确实是发送者发送的(没有被篡改,也不是伪造的)。公众也可以信赖这条信息确实来自与该用户,用户无法否认。
一般来说,不直接对消息进行签名,而是对消息的哈希值进行签名,并将签名附赠在消息一起发送。
总结一下二者的优点与缺点:
- 对称密钥加密(使用最广泛的 AES):加解密速度很快,强度也足够,但问题在于寻找一个安全通道让通信双方交换密钥很困难
- 公开密钥加密(使用最广泛的 RSA):加解密速度很慢,但可以解决通信双方安全通道的问题
故现在多将二者结合使用:需要加密的主体内容使用对称加密,对称加密的密钥使用非对称加密。
GPG 教程
下面说说如何使用 GPG 软件加密文件。
GPG 支持的算法有很多:
公钥:RSA, ELG, DSA, ECDH, ECDSA, EDDSA
对称加密:IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256,
TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256
散列:SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
压缩:不压缩,ZIP,ZLIB,BZIP2
对称加密
使用对称加密很简单,只需要一行就可以:
gpg --cipher-algo [对称加密算法名称] -c FILENAME
随后会让你输入两次密码,就会生成一个 FILENAME.gpg 的文件在同目录下。
解密:
gpg -o FILENAME -d FILENAME.gpg
更多参数请输入 gpg -h
自行查阅。
非对称加密
生成密钥
(这里如果输入的是 --gen-key
的话,会省去一些步骤:自动设置密钥尺寸为 2048 位、有效期限为 2 年、注释留空):
gpg --full-generate-key
回车后,出现以下文字:
gpg (GnuPG) 2.2.3; Copyright (C) 2017 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.
请选择您要使用的密钥种类:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (仅用于签名)
(4) RSA (仅用于签名)
您的选择?
选择 1:
RSA 密钥长度应在 1024 位与 4096 位之间。
您想要用多大的密钥尺寸?(2048)
选择 4096:
请设定这把密钥的有效期限。
0 = 密钥永不过期
<n> = 密钥在 n 天后过期
<n>w = 密钥在 n 周后过期
<n>m = 密钥在 n 月后过期
<n>y = 密钥在 n 年后过期
密钥的有效期限是?(0)
如果想设置 5 年过期,输入 5y,我这里是自己私人用,选择 0,随后会让你确认以上信息正确与否,输入 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>"
真实姓名:
电子邮件地址:
注释:
注释这一栏可以留空。
随后:
您选定了这个用户标识:
"×××××× <××@×××.com>"
更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)?
输入 o,会弹框提示设置一个密码,用于保护私钥。
与此同时,系统也会提示:
我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。
几秒后,系统就会提示密钥已经生成。
导出密钥
显示系统的私钥:
gpg -K
显示系统的公钥:
gpg -k
删除密钥:
gpg --delete-keys [uid]
gpg --delete-secret-keys [uid]
其中 uid 可以使用邮箱代替,下同。
导出公钥:
gpg -o public.key --export [uid]
导出私钥:
gpg -o private.key --export-secret-keys
这样导出的 key 文件是二进制,不可读,加上 –armor 参数可以保存为 ASCII 码形式。
导入密钥:
gpg --import [key 文件]
加密
gpg -r [uid] -o FILENAME.gpg -e FILENAME
-r 指定用户的公钥,如自己使用改为自己邮箱即可,-o 指定加密后输出文件名称。
解密
gpg -o FILENAME -d FILENAME.gpg
会让你输入密码,即用于保护私钥的密码。
参考: