来源:中国电子政务网 更新时间:2008-05-25
OpenSSL包含一个命令行工具用来完成OpenSSL库中的所有功能,更好的是,它可能已经安装到你的系统中了。
OpenSSL是一个强大的安全套接字层密码库,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,但是,你不应该只将其作为一个库来使用,它还是一个多用途的、跨平台的密码工具。
这里简单说一下OpenSSL的背景,在OpenSSL之前,叫做ssleay,它是一个由Eric A.Young编写的SSL工具,它不断改进最终变成了OpenSSL,与NCSA的HTTPd变成Apache
服务器的过程非常类似,今天,OpenSSL支持多种加密算法和协议。
OpenSSL有许多的特征,而且还有SSL客户端和服务端特征,OpenSSL还有:
◆美国联邦政府NIST FIPS 140-2一级评估确认
◆TLS,下一代SSL协议
◆X.509密钥和证书的生成
◆X.509证书权力
◆S/MIME加密
◆文件加密和粉碎
◆打乱UNIX密码
◆9个不同的商业密码硬件设备
◆密码性能测试
◆36个命令
◆6个消息摘要算法
◆9个密码算法
◆多个加密协议
尽管OpenSSL很复杂,但是大量的复杂性可以被避免的,本文剩下的部分将集中在易于使用的特征上,在shell代码中仅仅需要几行就可以了。
本文使用与我早期编写的GnuPG Hacks文章一致的小结标题,以便于比较OpenSSL和GnuPG。
入门 首先,确认一下OpenSSL已经安装并处于你的路径之下,许多Linux发行版,甚至一下小的发行版,都包括了OpenSSL,通常,OpenSSL处于/usr/bin/下。
在所有的例子中,shell提示符都是$。
第一步,输入:
$ openssl version
注意这里在version选项前是没有破折号的。
你应该看到类似下面这样的输出:
OpenSSL 0.9.7d 17 Mar 2004
准确的版本号,日期和其他可能不同的细节,写本文的时候,目前的版本是OpenSSL0.98a,我们正在使用的例子能工作在大部分OpenSSL版本下。
如果你只输入了openssl,没有附加任何的参数,你将得到下面这样的提示符:
OpenSSL>
如果是这样,只需要输入quit或按Ctrl-C即可安全地退出,它OpenSSL内部命令行提示符,它没有命令行编辑功能,也没有明确的帮助功能,但是,如果你输入一个它不认识的命令,它会列出一个可用的命令列表。
二进制文件保护 二进制文件典型地用于使用MIME的电子邮件,如果你的电子邮件软件不支持MIME,如大多数命令行电子邮件客户端,你将被uuencode困扰,你可以使用基于64位编码的OpenSSL,复杂的MIME协议也使用的是64位编码,但是它不能直接兼容MIME。
要使用64位编码打包二进制文件成文本文件,输入:
$ openssl base64 < filename.bin > filename.txt
要打开64位编码的文本文件,输入:
$ openssl base64 -d < filename.txt > filename.bin
注意OpenSSL不会关心文件扩展名。
OpenSSL与GnuPG或MIME不一样,它还能对短字符串进行编码,如下:
$ echo "The Linux Journal" openssl base64
VGhlIExpbnV4IepvdXJuYWwK
解码:
$ echo "VGhlIExpbnV4IEpvdXJuYWwK" openssl base64 -d
The Linux Journal
注意-d选项,它意味着解码。
更好的校验和 sum和cksum是传统的UNIX校验程序,它们工作得很好,只要你不需要跨平台兼容或安全,你也不用担忧会出现2个完全不同的文件有相同的校验和值。
尽管Linux系统经常安装了md5sum,MD5算法遭受了一个相对较新的漏洞,现在不应该使用它。如果它已经安装了,应该使用更安全的sha1sum,但是,一些版本只能同时对一个文件进行打乱,一些不能处理标准输入或者有其他的不足,如果你运行这些程序遇到了问题或者你想有一致的、比较知名的、具有良好跨平台的软件,建议考虑OpenSSL。
OpenSSL打乱输出格式与GnuPG有一点不同,但是数字是相同的,OpenSSL格式总是要鉴定使用的算法,并总是输出一个小写的无空白的十六进制的字符串,你会发现这种格式更容易使用。
这里有一些例子:
$ openssl sha1 filename
SHA1(filename)= e83a42b9bc8431a6645099be50b6341a35d3dceb
$ openssl md5 filename
MD5(filename)= 26e9855f8ad6a5906fea121283c729c4
在我早前的文章“GnuPG Hacks”中,上面的例子使用了一个包括字符串“The Linux Journal”的文件,注意这个字符串没有句号。
如果你复杂这些结果时遇到了问题,这里提供一个带ASCII注释的十六进制的表示,注意新行末尾是vi自动加上去的(图1):
OpenSSL与GnuPG不一样,它没有SHA-512加密算法,但是OpenSSL有MD2,MD4,MDC2,这些都是旧的算法了,只是为了保持向后兼容,和MD5一样,现在它们都不应该拿来使用。
快速整洁的加密 尽管这不是OpenSSL的强项,但它也能加密文件,灵活的OpenSSL做这件事要比GnuPG复杂一些。
OpenSSL默认选项比较少,因此要使用更多的选项,也有许多算法可供选择,一些算法如DES和RC4-40,只是为了向后兼容,现在不应该再拿来使用了,你应该使用强壮的算法如bf(它是Blowfilsh算法的简称)和-aes-128-cbc(它是美国NIST高级加密标准—AES,运行在CBS模式下使用128位密钥)。
这里有一个例子:
$ openssl enc -aes-128-cbc < filename > filename.aes-128-cbc
enter aes-128-cbc encryption password:
Verifying - enter aes-128-cbc encryption password:
与GnuPG一样,OpenSSL要求提供2次密语,并且不会回显到屏幕上。
解密也比GnuPG更复杂一点:
$ openssl enc -d -aes-128-cbc -in filename.aes-128-cbc > filename
enter aes-128-cbc decryption password:
注意例子中的-d参数,它意味着解密。
OpenSSL与GnuPG不一样,不能自动检查文件的类型或者使用了什么算法也不知道、也不清楚加密文件使用的密钥的长度和模式。你需要自己保存一个跟踪记录,在我的例子中,我将这些信息放在文件扩展名里了,OpenSSL不能为你管理文件和文件扩展名,你不得不指出输出数据写入的位置。
如果你没有指定正确的算法,OpenSSL可能输出一堆垃圾信息也可能产生一个看不懂的数字,无论怎样,没有正确的给出选项,你的数据就不能正确地解密。
密语 在我们更进一步之前,我们应该先讨论一下密语的重要性,在大多数加密系统中,密语是保存了其他机密的秘密,它通常是最薄弱的点,因此,创建一个强壮的密语是很重要的,但是这也很困难,除非你有好用的工具,使用OpenSSL你就能快速地创建一个强壮的密语。
一个对密语简单的指导就是长度与优势的比较表,8个字符不够长(表1),目标是创建一个保密性强的而且你又能记住的其他人又不知道的密语,不能靠猜或最后偶尔发现。
表1 密码和密语被破解的估计时间强度比较,注意:破解时间是比较粗糙的。
产生一个密语
OpenSSL能创建非常强壮的随机密语:
$ openssl rand 15 -base64
wGcwstkb8Er0g6w1+Dm+
如果你运行了这个例子,你的输出将与这里的输出不同,因为密语是随机产生的。
第一个参数15是产生的二进制字节数,第二个参数-base64指出那些二进制字节应该用基于64位字符编码,对于15字节而言,输出总是20个字符,加上一个新行字符。
基于64位字符设定了只由大写和小写的字母A-Z,数字1-9和3个标点字符:加号、斜线号和等号。这是一个有意的字符限制设置,更复杂的字符设置不是必需的,仅仅增加一个额外的字符使得安全变得不同,例如:一个8位字符完全可打印的ASCII密码大约与一个9位字符基于64位字符编码的密码强度相当。
尽管可以使用openssl rand快速生成密语,但是专业的密语生成器生成强壮的并容易记忆的密语,我强烈推荐使用它。
加密密码 还有一些事情是GnuPg不能做的,OpenSSL内置了一个命令用来创建加密的linux密码,就象/bin/passwd一样。
跳过这个段落避免陷入钻牛角尖的密码术,尽管通常叫做加密,linux密码实际上使用的是MD5或旧的UNIX密码打乱机制(基于DES加密算法),这就允许linux不知道你的密码,即使你提供了正确的密码让它知道了。当你设置你的密码时,linux打乱你的密码并保存在/etc/shadow中,当你登陆时,linux提取你输入的密码并再打乱一次,再与保存在/etc/shadow中的进行比较,如果匹配你提供的就是正确的密码,你就能登陆,如果不匹配,你也不清楚密码是好多了,因为存储的是打乱后的数据,计算机也不会知道你的密码是好多,反正你是不能登陆进去的。
这就是为什么打乱你自己的密码有用了,假设你在另一个计算机上需要一个新密码,或许它是一个新账号或你忘记了旧的密码让管理员给你重设密码,如果你能亲自告诉管理员,那么没有问题,但是如果管理员不在怎么办呢?或许你从来都没有和管理员见过面,你怎么传输你的新密码?电子邮件是不安全的,电话可能要好一点,邮寄一封信可能要好几天(可能会有其他安全问题),传真机,文本消息和大多数纸张上的东西是不安全的。
更糟糕的是,你可能不信任那个管理员,当然,管理员通常就是root,但是其他人可能知道你的密码,或许你象在其他机器上使用相同的密码,并且你也不信任那些机器的管理员。
因此,使用下面的方法:
$ openssl passwd -1
Password:
Verifying - Password:
$1$zmUy5lry$aG45DkcaJwM/GNlpBLTDy0
输入2次密码,它不会回显的,如果你有多个帐户,就运行多次上面的命令,输出的内容就是密码加密后的结果,由于采用的是随机加密,每次运行结果都是不一样的,即使密码是相同的。
在我的例子中,密码打乱后是这样的:
$1$zmUy5lry$aG45DkcaJwM/GNlpBLTDy0
你的密码打乱后可能与这里完全不同,除了开头的$1$。
打乱后的密码【译者注:实际上通常我们叫做hash值】就能用于电子邮件、传真、文本消息甚至通过电话交谈传输给管理员了,管理员据此可以重新设置你的密码hash值。
在管理员收到你的密码hash值后,它可以手动修改/etc/shadow或使用chpasswd命令,后面需要一个临时的新文件,叫做newpassword,你的登陆Id和密码hash值象这样:
LoginidHere:$1$ywrU2ttf$yjm9OXTIBnoKJLQK2Fw5c/
这个文件可以包括多行,为其他帐户提供类似的功能。
然后,管理员作为root登陆运行:
chpasswd --encrypted < newpassword
现在,新密码已经设置好了,一旦你登陆后立即修改你的密码是个好主意,除非你使用的是一个强壮的密语,这是因为密码hash值,一旦暴露,就成为离线强制破解的对象,除非这个密码是真的很长。
这个设置密码的方法是相当安全的,例如:使用这个技术,某个人能获取到密码hash值,创建一个账号,并知道登陆id和主机名,但是只有原先创建这个用户的人才知道密码,即使这个账号的密码hash值发布在杂志上也不用担心。
顺便说一下,那个hash值对应的密码是完全随机的基于64位字符编码的28位长,因此要破解它是非常困难的,但是请注意,不要用那些密码已经公布出来的hash值创建账号,如:
HXzNnCTo8k44k8v7iz4ZkR/QWkM2
密码和hash值象下面这样创建:
$ openssl rand 21 -base64
HXzNnCTo8k44k8v7iz4ZkR/QWkM2
$ openssl passwd -1 HXzNnCTo8k44k8v7iz4ZkR/QWkM2
这些例子使用MD5密码hash值,目前通用的linux系统都是这样,如果你需要使用旧的UNIX系统hash值,只需要去掉-1参数,例如:
$ openssl passwd
Password:
Verifying - Password:
xcx7DofWC0LpQ
最后这个密码hash值的密码是:TheLinux
密码基准测试 OpenSSL支持的许多算法使得它非常合适于密码基准测试,这对于比较相同硬件情况下不同算法的性能很有用,并且,它内置了一个基准测试命令。
openssl speed命令,默认情况下,在每个单独支持的模式和选项下运行每个单独的算法,使用不同的数据大小,不同的大小是重要的因为算法启动过头了。
完整运行speed需要花费大约6分钟时间,不考虑硬件的性能,产生29行摘要124行性能数据。
但是,注意加密算法的性能严重依赖特定的工具,对于高性能,OpenSSL在x86系统代码中有几个算法。其他结构如ia64,SPARC和x86-64,没有什么系统代码,没有列出的架构更没有了,系统代码放在OpenSSL源代码目录:crypto/*/asm,表2和表3节选了在3个不同的系统上的速度报告。
表2 hash和块密码性能(每秒使用1024字节块的数量是1000字节)
表3 公钥加密性能
学习更多
这仅仅是OpenSSL命令行功能的一个样本。在OpenSSL网站上有更多的文档,也有几个邮件列表提供技术支持。
OpenSSL使用c/c++编写的,但是它已经被移植到其他语言上去了,包括Ruby,而其,在2006年三月通过了FIPS140-2一级评估,使得OpenSSL称为一个新的在企业和政府加密领域的竞争者。