02.openssl之命令行
OpenSSL主要是一个由开发人员使用的库,在程序中包含了对强大加密技术的支持,但它也是一个可以从命令行访问其大部分功能的工具。 使用命令行工具可以轻松执行常用操作,例如计算文件内容的MD5散列。 更重要的是,命令行工具提供了从Unix上的shell脚本或Windows上的批处理文件访问大部分OpenSSL的更高级功能的能力。 它还为没有本地SSL绑定的语言提供了一个简单的界面,但可以运行shell命令。
毫无疑问,对于外行来说,命令行工具看起来相当复杂。 它包含了大量的命令,甚至更多的选项可以用来进一步细化和控制这些命令。 OpenSSL确实附带了一些涵盖命令行工具支持的大多数可用命令和选项的文档,但是即使这样的文档看起来也很吓人。 事实上,当您尝试发现创建自签名证书时,OpenSSL提供的文档不提供直观的方式来查找信息,即使它实际上在那里。
本章概述了命令行工具,提供了一些基本的背景信息,这些信息将有助于了解工具的命令结构是如何组织的。 我们还将提供有关如何完成许多常见任务的高级概述,包括使用消息摘要,对称密码和公钥密码术。 附录包含命令行工具支持的命令的参考。
2.1 The Basics
命令行工具可执行文件在Unix上被命名为openssl,在Windows上命名为openssl.exe。 它有两种操作模式:交互式和批处理。 程序启动时没有任何选项,它将进入交互模式。 在交互模式下运行时,会显示一条提示,指示它已准备好处理您的命令。 每个命令完成后,提示符会重新显示,并再次准备好处理另一个命令。 该程序可以通过简单地发出quit命令退出。 以交互模式输入的命令的处理方式与您在批处理模式下从命令行输入的命令完全相同。 唯一的区别是你不需要在每个命令前输入“openssl”。 在我们的示例中,我们通常会以批处理模式操作该工具,但如果您觉得使用交互模式更加舒适,那很好。
2.1.1 Configuration Files
命令行工具为其许多命令的每一个提供了大量的选项。 记住选项名称,如果没有指定它们的缺省值,甚至包括一个命令以获得期望的结果,可能是困难的,即使不是彻头彻尾的挫败感。 管理选项的任务使用配置文件变得相当简单。
不幸的是,命令行工具支持的许多命令中只有三个使用了配置文件。 好的一面是,使用它的三个命令可能是所有支持的命令中最复杂的,并且接受最多的选项来控制它们的行为。 支持配置文件的命令是ca,req和x509(我们将在下面讨论这些命令)。
2.2 Message Digest Algorithms
在第1章中,我们介绍了密码散列函数,更好地称为消息摘要算法,它可以用来计算一个数据块的校验和。 OpenSSL包括对MD2,MD4,MD5,MDC2,SHA1(有时称为DSS1)和RIPEMD-160的支持。 SHA1和RIPEMD-160产生160位散列,其余都产生128位散列。 除非您需要兼容性,否则我们建议您仅使用SHA1或RIPEMD-160。 SHA1和RIPEMD-160都为通用性提供了极好的安全性,但是SHA1更为常见。 MD5是一种非常受欢迎的消息摘要算法,但是对于所有的应用程序来说它并没有很好的安全性。 我们在第7章中详细讨论消息摘要。
OpenSSL奇怪地处理SHA1。 有些地方你必须把它称为DSS1(dgst命令,稍后介绍),有些地方你不能把它称为DSS1(其他地方)。 这是实施的一个限制。 使用SHA1作为名称,除非我们特别提到您需要使用DSS1。
命令行工具提供了使用大多数支持的算法的命令。 dgst命令是访问消息摘要的主要命令,但大多数算法可以使用与算法同名的命令来访问。 例外是RIPEMD-160,它被命名为rmd160。
使用任何消息摘要命令执行的默认操作是计算一个数据块的散列值。 该数据块可以从标准输入读取,也可以是一个或多个文件。 当使用多个文件时,会为每个文件计算单独的散列值。 默认情况下,除非指定了备用输出文件,否则所计算的哈希值或散列值将以十六进制格式写入标准输出。
除了计算散列之外,还可以使用消息摘要命令来签名和验证签名。签名或验证签名时,一次只能使用一个文件;否则,签名将一起运行,最终难以分离成可用的形式。签名时,将为要签名的文件的散列生成签名。私钥需要签名,可以使用RSA或DSA。当您使用DSA私钥时,您必须使用DSS1消息摘要(尽管它与SHA1算法相同)。您可以使用除DSS1以外的任何算法和RSA私钥。验证签名就是签名的反面。通常情况下,需要一个公钥来验证签名,但是一个私钥也可以工作,因为公钥可以从私钥中获得,反之亦然。在使用公钥或私钥RSA密钥验证签名时,还需要知道使用哪种消息摘要算法来生成签名。
2.2.1 Examples
a. 对文件file.txt 输出sha1并输出stdout
$ openssl dgst -sha1 file.txt
b. 对文件file.txt 输出sha1并输出digest.txt文件
$ openssl sha1 -out digest.txt file.txt
c.. 使用DSA(dsakey.pem)的私钥,对file.txt文件进行算法SHA1签名.PEM为一种广泛使用的加密方式。dsasign.bin文件产生原始2进制文件。
$ openssl dgst -dss1 -sign dsakey.pem -out dsasign.bin file.txt
d. 使用DSA(dsakey.pem)的私钥,对file.txt文件进行算法SHA1验签.
$ openssl dgst -dss1 -prverify dsakey.pem -signature dsasign.bin file.txt
e.使用RSA( rsaprivate.pem)的私钥,对file.txt文件进行算法SHA1签名
$ openssl sha1 -sign rsaprivate.pem -out rsasign.bin file.txt
f.使用RSA (rsapublic.pem)公钥,对file.txt文件践行算法SHA1验签
$ openssl sha1 -verify rsapublic.pem -signature rsasign.bin file.txt
2.3 对称密码
OpenSSL支持各种各样的对称密码。 当然,这些密码也可用于命令行工具。 许多大量的密码是基本密码的变体。 命令行工具支持的基本密码是Blowfish,CAST5,DES,3DES(三重DES),IDEA,RC2,RC4和RC5。 OpenSSL 0.9.7版增加了对AES的支持。 大多数受支持的对称密码支持多种不同的模式,包括CBC,CFB,ECB和OFB。 对于每个密码,如果未明确指定模式,则默认模式始终为CBC。 每个支持的对称密码及其各种操作模式将在第6章详细讨论。特别要提到的是,一般不要使用ECB,因为安全使用难以置信。
enc命令是访问对称密码的主要命令,但是也可以使用与密码同名的命令来访问每个密码。 使用enc命令,使用带有密码名称的选项指定密码。 不管所使用的命令的密码或形式如何,每个密码接受相同的选项来控制命令的功能。 除了使用对称密码来提供数据的加密和解密之外,base64命令或enc命令的选项也可以用于base64中的数据的编码和解码
使用任何密码命令执行的默认操作是对数据进行加密或base64编码。 通常,从标准输入读取数据并写入标准输出,但可以指定输入和输出文件。 一次只能对一个文件进行加密,解密,base64编码或base64解码。 在加密或解密时,可以指定一个选项,在加密之后执行base64编码,或在解密之前执行base64解码。
当执行加密或解密时,每个密码都需要一个密钥。 回想一下第一章对称密码的简要讨论,关键是提供对称密码的安全性。 与传统的密码技术相比,现代密码算法被广泛使用,可以被任何有时间和兴趣的人仔细研究。 用于加密数据的密钥必须仅为您和加密数据的预期收件人或收件人所知。
密码可以使用pass选项指定,根据本章后面概述的密码和密码的一般原则。 如果没有指定密码或密钥信息,工具将显示一个提示来获取它。
2.3.1 Examples
a.使用算法3des 模式cbc加密plaintext.doc加密保存数据 ciphertext.bin
$ openssl enc -des3 -salt -in plaintext.doc -out ciphertext.bin
b.使用算法3des 模式ofb解密plaintext.doc加密保存数据 ciphertext.bin
$ openssl enc -des3-ede-ofb -d -in ciphertext.bin -out plaintext.doc -pass pass:trousers
c.使用算法3des 模式cfb加密plaintext.doc加密保存数据 ciphertext.bin
$ openssl bf-cfb -salt -in plaintext.doc -out ciphertext.bin -pass env:PASSWORD
d.在base64中编译文件ciphertext.bin的内容并将结果写入文件base64.txt。
$ openssl base64 -in ciphertext.bin -out base64.txt
e.使用算法rc5
向量iv E9EDACA1BD7090C6 ;
密钥 -K 89D4B1678D604FAA3DBFFD030A314B29
输出文件: ciphertext.bin
$ openssl rc5 -in plaintext.doc -out ciphertext.bin -S C62CB1D49F158ADC -iv E9EDACA1BD7090C6 -K 89D4B1678D604FAA3DBFFD030A314B29
2.4 Public Key Cryptography
SSL协议在很大程度上依赖于各种不同的密码算法,包括消息摘要算法,对称密码和公钥密码。 其大部分这些算法的使用通常在不需要任何人为干预的情况下完成。 但是,一个普遍的例外是使用公钥密码。 例如,为了使服务器采用SSL协议,它需要私钥和证书。 证书包含与服务器的私钥匹配的公钥。 必须将这些密钥创建为配置服务器使用SSL的过程的一部分,而且这些密钥通常不会自动创建。 相反,它们必须由配置服务器的人创建。
SSL不是使用公钥密码术的唯一协议。 大多数支持加密通信的现代软件也都使用它。 一些比较流行的例子包括SSH,PGP(Pretty Good Privacy)和S / MIME。 所有这些例子都以某种形式使用了公钥密码学,我们也忽略了许多其他的应用。 我们将在第8章详细讨论OpenSSL对公钥加密的支持。
2.4.1 Diffie-Hellman
简而言之,密钥协议是通过不安全介质交换信息,允许对话双方中的每一方计算通常用作对称密码密钥的值。
Diffie-Hellman通过首先创建一系列双方在会话中达成一致的参数来工作。 由随机选择的素数和通常指定为2或5的生成器值构成的参数是公开的,并且可以在对话开始之前或者作为对话的一部分交换时被同意。 使用商定的参数,每一方计算公钥和私钥。 顾名思义,私钥永远不会与任何人共享。 各方交换其公钥,然后各方可以使用他们的私钥和对方的公钥来计算共享密钥。
命令行工具提供了用于生成Diffie-Hellman参数的命令,但生成密钥的唯一方法已弃用,因此不应使用。 OpenSSL 0.9.5添加了dhparam命令,并且这样做,弃用了两个命令dh和gendh,这两个命令分别能够生成Diffie-Hellman参数和密钥。 在写这篇文章的时候,两个不赞成使用的命令在OpenSSL 0.9.7中仍然可以访问,但是由于它们已经被弃用,所以我们会假装它们不存在,因为它们可能会从下一个版本的OpenSSL中完全删除。 不幸的是,新的dhparam命令不支持生成Diffie-Hellman密钥,但未来的版本可能会增加对它的支持
2.4.1.1 Examples
a.产生一对新的RSA密钥对参数密钥
$ openssl dhparam -out dhparam.pem -2 1024
b从文件dhparam.pem读取一组Diffie-Hellman参数,并将参数的C代码表示写入stdout。
$ openssl dhparam -in dhparam.pem -noout -C
2.4.2 Digital Signature Algorithm(数字签名)
顾名思义,数字签名算法(DSA)用于创建和验证数字签名。 它提供身份验证,但不能用于加密或保密。 DSA经常与Diffie-Hellman结合使用。 对话中的双方可以在对话开始之前(或者在使用证书进行对话的过程中)交换DSA公共密钥,并且使用DSA密钥来验证DiffieHellman参数和密钥的通信。 将Diffie-Hellman与DSA结合提供认证和TEAMFLY保密性,并且通过使用由Diffie-Hellman交换产生的共享密钥作为密钥,然后可以使用对称密码进行加密。
就像Diffie-Hellman一样,DSA也需要生成密钥的参数。 使参数用于生成一个密钥对是公共的没有什么坏处,但同样没有强制性的理由这样做。 只有生成的私钥必须保密,如其名称所暗示的那样。 公共密钥是唯一真正需要与希望验证用私钥签名的任何真实性的任何一方共享的东西
命令行工具提供了三个命令,用于生成DSA参数和键,以及检查和操作它们。 dsaparam命令用于生成和检查DSA参数。 它的功能和选项与dhparam命令不同。 两者之间的一个主要区别在于,dsaparam命令还提供了一个生成专用DSA密钥的选项。 由dsaparam命令产生的私钥将是未加密的,这意味着密码和密码短语都不需要解密和使用它。
gendsa命令用于从一组DSA参数中生成私钥。 默认情况下,生成的私钥不会被加密,但是可用的选项允许使用DES,3DES或IDEA密码中的任何一种对密钥进行加密。 没有提供选项来指定在命令行中用于加密的密码或密码短语,因此加密的DSA私钥生成不容易自动化。
dsaparam和gendsa命令都可以生成私钥,无论是否加密,但都不具备生成公钥的能力,这是DSA提供的任何公用密钥所必需的。 dsa命令提供了从私钥生成公钥的方法。 它还允许对私钥上的加密进行更改。 对于未加密的私钥,可以添加加密,对于已经加密的私钥,可以更改密码或密码以及用于加密密码的加密密码。 使用这个命令也可以删除私钥上的加密。
2.4.2.1 Examples
a.产生数字签名的密钥对(1024bit位)
$ openssl dsaparam -out dsaparam.pem 1024
b.产生一组的DSA私钥
$ openssl gendsa -out dsaprivatekey.pem -des3 dsaparam.pem
c.产生一组DSA公钥对
$ openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem
d.更换密钥
$ openssl dsa -in dsaprivatekey.pem -out dsaprivatekey.pem -des3 -passin pass:oldpword -passout pass:newpword
2.4.3 RSA
RSA是目前使用最广泛的公钥算法,尽管它在2000年9月专利到期之前一直受到专利限制的束缚。它以其创建者Ron Rivest,Adi Shamir和Leonard Adleman的名字命名。 其中一个非常受欢迎的原因是因为它提供了一个整洁的小包装中的保密,认证和加密。
rsa命令用于操作和检查RSA密钥,并且是DSA密钥的dsa命令的RSA版本。 它能够添加,修改和删除保护RSA私钥的加密。 它也能够从私钥生成RSA公钥。 该命令也可以用来显示有关公钥或私钥的信息。
rsautl命令提供了使用RSA密钥对进行加密和签名的功能。 提供了用于加密和解密数据的选项,以及用于签名和验证签名的选项。 请记住,签名通常是在散列上执行的,所以这个命令对于签署大量的数据,甚至超过160位的数据是没有用的。 一般来说,我们不建议您使用这个命令来加密数据。 您应该使用enc命令。 另外,使用RSA的加密和解密很慢,因此不应该单独使用。 相反,它通常用于加密对称密码的密钥。 这在第8章中有更详细的讨论。
2.4.3.1 Examples
a.产生1024bit公钥对
$ openssl genrsa -out rsaprivatekey.pem -passout pass:trousers -des3 1024
b.产生公钥
$ openssl rsa -in rsaprivatekey.pem -passin pass:trousers -pubout -out rsapublickey.pem
c.使用公钥对文件plain.txt进行加密
$ openssl rsautl -encrypt -pubin -inkey rsapublickey.pem -in plain.txt -out cipher.txt
d.使用私钥对文件plain.txt进行解密
$ openssl rsautl -decrypt -inkey rsaprivatekey.pem -in cipher.txt -out plain.txt
e.使用私钥进行签名
$ openssl rsautl -sign -inkey rsaprivatekey.pem -in plain.txt -out signature.bin
f.使用公钥进行验签
$ openssl rsautl -verify -pubin -inkey rsapublickey.pem -in signature.bin -out plain.txt
2.5 S/MIME
S / MIME代表Secure Multipurpose Internet Mail Exchange。 RSA Security于1995年与其他几家软件公司合作开发了最初版本; IETF开发了第3版。与PGP一样,S / MIME也提供加密和认证服务。公钥基础设施被用作建立信任的手段,这意味着S / MIME能够扩展以支持大群人。缺点是需要使用公钥基础设施,这意味着设置起来要比PGP稍微困难一些,因为证书必须从任何使用证书加密或验证通信的人信任的证书颁发机构获得。公钥以X.509证书的形式交换,这要求证书颁发机构颁发可以使用的证书。由于证书颁发机构涉及公钥的交换,因此如果颁发证书的证书颁发机构是可信的,则可以建立信任。第3章详细讨论了公钥基础设施。
2.5.1 Examples
smime 加密
$ openssl smime -encrypt -in mail.txt -des3 -out mail.enc cert.pem
smime 解密
$ openssl smime -decrypt -in mail.enc -recip cert.pem -inkey key.pem -out mail.txt
smime 签名
$ openssl smime -sign -in mail.txt -signer cert.pem -inkey key.pem -out mail.sgn
smime 验签
$ openssl smime -verify -in mail.sgn -out mail.txt
2.6 Passwords and Passphrases
许多命令(尤其是涉及私钥的命令)需要密码或密码才能成功完成,通常用于解密安全存储在磁盘上的密钥。 通常情况下,即使您没有以交互模式运行工具,34命令行工具也会提示您输入密码或密码。 在需要使用计算机上的键盘的人时,需要输入密码或密码短语,这使得使用自动化工具的工具很困难,至少可以这么说。
密码参数输入:
stdin
pass:<password>
env:<variable>
file:<filename>
.