加密及密码体制原理介绍
在进行相关的渗透的时候, 可能需要使用SSL. 即使不是从事渗透, 但是为了安全起见, 我们还是使用OpenSSL工具加强数据安全性. 无论如何, 这是密码学的一个应用, 它可以起到十分强大的作用. 事实上是所有的文件加密的重要的, 几乎是唯一现代化的方法.
密码学的一些常识我们必须了解. 现体密码体制中, 密码算法都是公开的, 保密指的是密钥的保密, 而不是算法的保密. 因为研制一个算法是非常麻烦的, 且作为学术上的东西, 它必须还要为人广泛地知道. 这也许体现了人类活动的一个基本准则, 那就是学术开放重要于人类活动. 也就是说, 原理是人类共有的, 应用的不同, 只是人们理解上的差异. 核心的知识是人类共知的, 而那些不为了所知的, 只是用于短期需求, 且没有长久的价值.
密码体制中, 大概有这样几种类型, 加密, 哈希与签名. 它们各自有一套原理.
其中加密又分为对称加密与不对称加密. 不管它们是如何实现的, 我们都可以用通用的公式来说明. 假设加密方有加密函数 \(E\) , 解密方有函数\(D\) , 原消息 \(M\) ,而所使用的密钥是 \(K\) , 那么加密解密过程分别是:
- 加密过程\[E(M,K) = C\]
- 解密过程\[D(C,K) = M\]
在加密解密函数相互配套的情况下, 双方均需知道 \(K\) 的值. 在发送的时候, 加密方只在不安全信道上传输密文 \(C\) , 解密方只需要使用 \(K\) 解出密文 \(C\) 为 \(M\) .
我们可以分析, 实行加密的过程是算法规定的, 因此任何人都可以. 但是一个攻击者将因为无法知道和解密方相同的 \(K\) 而不能伪造与解密方通信—如果它对 \(K\) 一无所知而又试图发送密码, 那么解密出来的, 往往是随机的文字, 以致于攻击者自己也不知道解密方将会看到什么消息, 因此这种攻击就失去意义.
对称加密的主要问题在于如何达成一致的密钥. 由于 \(K\) 需要保密, 因此得事先由发送方与接收方秘密约定, 或使用额外的安全信道. 尽管如何, 对称加密因为速度上的原因, 以及能够配合其它体制使用, 因此也颇有应用. 主要的对称算法有DES, AES, RC4等.
非对称加密一定意义下等同于公钥体制. 将体制下, 密钥分成公钥与私钥两个部分. 它们是成对出现的, 且公钥可以公开发布, 只是人们很难从公钥 \(K_1\) 推出私钥 \(K_2\) .加密与解密过程分别为:
- 加密过程\(E(M, K_1) = C\)
- 解密过程\(D(C, K_2) = M\)
符合这一原理的方法有RSA(基于因子分解), ElGamal(基于离散对数)等.
另外, 离散对数问题可以用于密码协商, 进一步保证前向安全. 基于它的著名协议是Diffie-Hellman密钥协商协议. 协商基本过程是, \(A\) , \(B\) 双方各自选择仅自己知道的数字(即使对方也不知道), 根据离散对数分别计算明文. 各自接收到对方的明文后, 再计算一次可以得到相同的数字. 该数字即为协商的结果. 该方法的特点是双方各自不知道对方的密码, 但是却可以维持一个仅能双方知道的加密信道. D-H协议的主要问题是协议中没有关于通信双方身份的验证, 因此可能被一个中间人物在协商时截取, 形成一个代理.
HASH技术原本是为了方便和提高速度, 而对数据完整性校验, 但与密码体制结合起来, 也可以用于数字签名. 主要的HASH函数有MD5, SHA1等.
配合HASH进行数字签名的原理是, 双方本来就已经协商好了密码体制. 这个时候, 规定消息格式由消息体和HASH两个部分规范地组成. 根据具体情况, 如果消息可以明文传递, 那么就发送消息明文和加密后的消息HASH, 对方自动计算消息HASH, 并与解开发送方加密的HASH对比就可以了; 如果是密文加密, 亦是类似.
公钥算法的特点是太慢, 因此实际使用公钥的时候, 常用公钥算法传输会话密钥, 再用对称算法加密传递批量数据.
公钥的发布是公钥体制的核心. 一般设立权威中心(CA), 由CA以数字签名的方式签发公钥, 即证书. 证书中包含有公钥, 持有人信息, 用途说明, 有效期, 签发人的数字签名等. 有了对方的证书后, 可以让对方签名来看看, 如果对方发过来的消息中, 能够签出这个公钥验证的名, 则可确认对方应当有对应私钥; 否则对方就是假冒的.
注意, 持有证书的人虽然能够验证签名者的真伪, 但是却不能通过消息推导出签名者的私钥—否则证书体制将会面临重大缺陷.
OpenSSL简介与基本使用
OpenSSL是使用非常广泛的SSL开源实现. 由于其中实现了为SSL所用的各种加密算法,因此OpenSSL也广泛被视为开源的加密函数库—更保况它的确提供了接口函数.
OpenSSL学习的基础环境是openssl命令行. 输入 openssl 命令, 即可进入. 在其中可以执行OpenSSL所提供的各种功能. 比如, 生成随机数, 产生密钥对.
其中较为简单的HASH验证, 产生随从数就不说了. 只是最重要的密钥与加密.
要使用OpenSSL, 我们要知道它有哪几个方面的基本用途. 第一个是非对称加密, 第二个是对称加密, 第三个则是信息摘要算法. 其实信息摘要算法是很简单的, 也就是我们所说的MD5等HASH算法.
对称加密算法
对称加密算法的基本流程是, 在一定的对称加密算法的支持下, 输入密码, 指定输入文件, 然后得到一个输出文件. 将输出发送到另外一台机器上, 在另外一台机器上应用相同配置即可解密出文件.
OpenSSL提供的主要的工具是 enc 命令. enc -e用于加密, enc -d用于解密. 执行命令
openssl enc -des -e -a < source.txt > source.txt.des进入对话框, 输入密码之后就可以生成加密后的文件了, 再使用
openssl enc -des -d -a < source.txt.des > source.txt就可以恢复想要的 source.txt 文件.
对称加密之间的不同, 主要在于所选用的对称加密算法, 比如 -des . 使用对称加密的时候, 其实也应当注意, 一个长度较少的密码, 是容易被攻破的, 因此不妨选用更长位数的密码. 这样, OpenSSL可以使用 -k , -kfile 选项从命令行选项, 或者从文件中得到密码. 不用在线输入.
非对称加密算法
非对称加密算法的应用范围更广. 而且也有助于产生更长的密码. 非对称加密的原理已经介绍过了. 因此在本地产生钥匙对是最基础的. 对应OpenSSL命令为:
openssl genrsa 1024 > hawk.key产生ASCII编码的RSA钥匙对. 可以用
openssl rsa -noout -text < hawk.pem查看包含在 hawk.pem 当中的公钥与私钥的值.
为了更安全起见, genrsa 还支持将生成的钥匙对使用对称加密算法加密, 比如加上 -des 选项后, 以后要再想用这个钥匙对, 必须输入一个密码才行.
不管怎么说, 第一步产生钥匙对的工作总算是完成了. 此时用
openssl rsa -pubout <hawk.key >hawk_pub.pem可以仅导出RSA中的公钥的那个部分, 直接引用 hawk_pub.pem 以发布公钥. 对于DSA, 需要在生成密码的时候提供一个参数. 因此过程是
openssl dsaparam 1024 > dsaparam.pem
openssl gendsa -des3 <deaparam.pem >private.pem ## 生成密钥
openssl dsa -pubout <private.pem >public.pem ## 导出公钥这要比RSA方式复杂一步.
产生了钥匙对, 便可以分别使用私钥与公钥对文件签名与验证了. 比如
## signature
openssl dgst -sha1 -sign private.pem <file.txt >file.txt.sgn
## verify
openssl dgst -sha1 -sign public.pem <file.txt.sgn >file.txt不过我们不一定是对整个文件加密, 而是更有可能是对文件的摘要加密.
注意, 这是对文件签名与验证. 前提是接收方有正确的公钥. 如果一开始得到的是窃取者的公钥, 那么窃取者就能伪造发送方与接收方通信.
信息摘要算法
信息摘要算法对于验证文件有时是非常有效的. 对于较弱的验证, 比如看从网上下载的一个文件与服务器一样与否, 可以用|openssl sha1 file.txt|得到SHA1值, 然后与服务品的上对比.
信息摘要算法的另一个应用是保存用户的密码, 前提是保存用户密码的地方, 其它人不能任意修改相应的摘要. 在用摘要算法保存密码的时候, 还可以加上一些噪声, 防止被用常用词摘要表的方法攻破.
密码管理是 passwd 命令, 它可以以UNIX标准的方式加上一个密码, 以及加上一些噪声. 在服务器存储密码的时候特别有用, 比如
openssl passwd -1 -salt 分别以password为输入文件, 和以使用摘要算法后的密码为输出文件.
OpenSSL还有其它的许多功能. 有用到的时候可以参考其手册.
GnuPG工具
GnuPG也算是密码学工具. 相对于SSL, 大概长处在于封装了一整套的方案. 面对主流的应用, gnugp直接提供了相应的命令, 相对于密码学工具, 更侧重应用.
GnuPG可以完成几乎全部现行密码体制. 对称加密解密, 非对称加密解密, 数字签名与认证等. 由于已经有了OpenSSL的背景, 我们讲GnuPG的应用.
GnuPG基本上可以看成是管理本地的公钥私钥的工具. 不仅可以管理自己创建的钥匙对, 还可以管理从网上下载的公钥私钥. 甚至可以发展成一个集团认证的工具, 因为对于一个签名的文档, 使用者还可以自己再加上一个签名, 从而让用户知道已经有很多人对这一个公钥认证过, 因此大大增强了信心.
GnuPG的基础命令有|gpg –gen-key|与|gpg -k/-K|, 分别用于生成钥匙与查看本机的所有的钥匙. GnuPG管理它们的时候, 对钥匙文件使用 Key_ID 标识. 也就是说, 使用哪个文件, 通过 Key_ID 来指定.
导出公钥
示例命令:
gpg --export --armor Key_ID > Key_ID_pub.pem
gpg --export Key_ID > Key_ID.gpg分别表示导出ASCII格式与二进制格式的公钥. 同时, 导入另人的公钥, 使用
gpg --import Key_ID_pub.pem公钥总是要发布出来才有意义, GnuPG提供的命令可以直接将公钥发布到网上, 以及从网上的服务器上下载公钥. 这里有一个可用的公钥服务器 keys.gnupg.net .
gpg --keyserver keys.gnupg.net --send Key_ID从服务器上下载相应的公钥, 则可以调用
gpg --keyserver keys.gnupg.net --recv-keys Key_ID其实使用默认服务品的话, 可以不用指定 keyserver 的, 默认服务器可以在.gunpg/gpg.conf文件中配置.
钥匙管理
按照GnuPG的基本的意思, 应该是把公钥导出, 在本地有一个私钥就行了. 但是有时候, 因为重装系统等原因, 可能需要导出以迁移私钥. 方法是:
gpg --export-secret-keys --armor Key_ID > Key_ID.pem直于在另一台机器上导入私钥, 则是同样的道理.
从上面的流程, 我们可以看出, 一个完整的 Key_ID 文件中, 不仅有公钥与私钥, 还有用户相关的信息, 以及加密私钥的密码, 只有提供了密码, 才能从 Key_ID 中提取重要数据. 因此一个 Key_ID 可以用于多种用途, 非对称加密, 签名均可.
吊销证书
该功能可以看成是 Key_ID 机制的扩展. 当一个符合要求的证书因为某种原因, 状态发生变化的时候, 可以根据吊销证书被取消. 当然, 创建吊销证书的, 必须是发布机构, 也就是知道私钥与密码的那个人. 产生相应 Key_ID 的吊销证书后, 在相应的时机, 导入此证书, 便可以使相应 Key_ID 的证书失效.
gpg --gen-revoke Key_ID > Key_ID.rvk.pem导入吊销证书的方法, 与导入一个公钥使用相同的命令.
对称加密
默认GnuPG使用的是非对称加密的方法. 所以要想使用对称加密, 虽然原则上与OpenSSL相同, 但是参数形式要稍微长一些, 或者难记一些.
## 对称加密并生成filename.asc文档. 不带armor, 生成gpg二进制格式.
gpg --armor -c filename
## -c 等同于命令 --symmetric
## 对称解密时输入相应的密码即可
gpg --armor -d filename.asc
## -d 等同于 --decrypt 选项非对称加密
既然在 .pem 文件中, 所有的要素都准备了, 那么非对称加密也就不困难了. 使用
gpg --armor -r Key_ID -e filename解密的时候, 与对称加密的时候相同. 只不过解密的时候, 需要存有私钥的Key_ID文件.
数字签名
对文件进行数字签名也是很简单的, 示例如下:
## 对文件签名, 并且将文件签到输入文件中
gpg --sign filename -o filename.gpg
## 生成文件与HASH分开的签名
gpg --detach-sig filename -o filename.sig也可以通过类似 --armor 的选项, 导出ASCII格式的签名的文件, 这样更易于在互联网上传播( --clearsign 选项).
至于验证签名, 则可以使用 --verify 选项.
GnuPG还有其它很多用法, 比如在一个公钥上签上自己的名. 这里就不多讲了.