一、openssl简介
openssl是最著名的开源SSL,其用 C 实现,被广泛应用在基于TCP/Socket的网络程序中。
OpenSSL:开源项目
三个组件:
openssl: 多用途的命令行工具,包openssl
libcrypto: 加密算法库,包openssl-libs
libssl:加密模块应用库,实现了ssl及tls,包nss
1、SSL(Secure Sockets Layer,*接层)是一个安全协议,为基于TCP的应用层提供安全链接,如https。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。目前,利用公开密钥技术的SSL协议,已成为Internet上保密通讯的工业标准。SSL协议被广泛应用于电子商务、网上银行等领域,为网络上数据的传输提供安全性保障。
SSL协议位于TCP 协议层和应用层之间(即在会话层或表示层),当数据经过它流出的时候被加密,再往TCP/IP 送,而数据从TCP/IP 流入之后先进入它这一层被解密,同时它也能够验证网络链接两端的身份。
通过SSL可以实现:
连接的私密性:在SSL 握手阶段生成密钥后,用对称加密算法对传输数据进行加密。
身份认证:对服务器和客户端进行基于证书的身份认证,其中客户端认证是可选的。
连接的可靠性:消息传输过程中使用基于密钥的MAC(Message Authentication Code,消息验证码)来检验消息的完整性。
2、TLS(Transport Layer Security)
1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。
1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。
1996年,SSL 3.0版问世,得到大规模应用。
1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。
2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2(目前使用最多的)的修订版。
SSL、TLS功能:机密性,认证,完整性,重放保护(重放的意思是,拒绝相同的包,避免重放攻击)
3、基本的运行过程
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。这时client端已经拿到公钥了,由于非对称加密算法在解密的过程中,耗时巨大,所以通过非对称秘钥来加密传输的数据显然不合逻辑,所以就有了这种方法–通过非对称秘钥来加密对称加密的秘钥(数据量小,不会产生耗时巨大的弊端),以确保双方协商传输的对称秘钥不会被篡改,真正的数据传输,实际用的是对称加密的方法。
但是如果要保证server向client端传输的公钥不被篡改,则需要用证书对公钥进行签名,如果证书是可信的,那么公钥就是可信的。
SSL/TLS协议的基本过程是这样的:
(1) 客户端向服务器端索要并验证公钥。(明文传输,可以被篡改,需要证书来验证公钥的来源是否正确)
(2) 双方协商生成”对话密钥”。
(3) 双方采用”对话密钥”进行加密通信。
4、握手阶段的详细过程( Handshake协议)
1)、客户端请求建立SSL链接,并向服务端发送一个随机数–Client random和客户端支持的加密方法,比如RSA公钥加密,此时是明文传输。
2)、服务端回复一种客户端支持的加密方法、一个随机数–Server random、授信的服务器证书和非对称加密的公钥。 (如果客户端不支持服务器端的算法,服务器端将关闭连接)
3)、客户端收到服务端的回复后利用服务端的公钥,加上新的随机数–Premaster secret 通过服务端下发的公钥及加密方法进行加密,发送给服务器。
4)、服务端收到客户端的回复,利用已知的加解密方式进行解密,同时利用Client random、Server random和Premaster secret通过一定的算法生成HTTP链接数据传输的对称加密key – session key。(DH Deffie-Hellman)
经过这4个阶段之后,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,使用的就是普通的HTTP协议,只不过用对称秘钥加密内容。
二、openssl的基本应用
openssl的基本应用有:对称加密、 单向加密、生成用户密码、生成随机数、对称加密
1、openssl的对称加密:
- [root@newhostname app]# ls
- fist_encrypt
- [root@newhostname app]# openssl enc -e -des3 -a -salt -in fist_encrypt -out fist_encrypt.des3
- enter des-ede3-cbc encryption password:
- Verifying - enter des-ede3-cbc encryption password:
- enc :表示对称加密
- -e :表示要执行的动作是加密 相反的 -d表示解密
- -des3: 表示钥使用的算法是des3
- -a : 表示base64编码(base64:A-Za-z0-9+/,这些组合在一起,总共64个)
- -salt : 表示加盐,默认就表示加盐
- -in : 表示输入,我们选择的是fist_encrypt这个文件
- -out : 表示输出,我们将新生成的文件命名为fist_encrypt.des3
- [root@newhostname app]# openssl enc -d -des3 -a -salt -in fist.des3 -out new_file #解密的参数与加密的参数要对应好
- enter des-ede3-cbc decryption password:
可以通过“man enc”来查看对称加密的各种选项和算法
2、单向加密
- [root@newhostname app]# openssl dgst -md5 -hex fist.des3
- MD5(fist.des3)= bd7c8c96452aff39b63049cd0696b47d
- [root@newhostname app]# openssl dgst -sha1 fist.des3
- SHA1(fist.des3)= 0d1b1a6594ba7ff72e78558eb55fe5c5877bcda2
- dgst:表示单项加密
- -md5、-sha1 :表示算法
- -hex :表示已16进制的格式输出; dgst支持很多种格式输出,可以通过man dgst来查看
- 以上的命令相当于
- md5sum fist.des3
- sha1sum fist.des3
可以通过man dgst来查看openssl所支持的选项和其所支持的算法,直接man openssl是查不到的。
3、生成密码
- [root@newhostname app]# openssl passwd -1
- Password:
- Verifying - Password:
- $1$oWzC5Ru.$XVxqgrenwYJ.g8xbnnoWz0
- passwd:表示生成密码
- -1:表示使用md5算法
- -salt:表示加盐,也可以自己指定,如: -salt "dddeeeed" (字符串最多8位) 上述操作,我们并没有指定 -salt选项,该选项为系统默认添加。上述“$1$oWzC5Ru.$”表示盐的部分
- 我们通常会用这个命令来生成用户的口令加密串,其格式和/etc/shadow 下的第二个字段格式完全一样。
4、生成随机数
- [root@newhostname app]# openssl rand -base64 20
- EDQIGyLyswYmbjCoYmylb3RcPmE=
- [root@newhostname app]# openssl rand -base64 22
- HzFIds+ni82PiTd5Zw6gsJGBVFx/Vw==
- [root@newhostname app]# openssl rand -hex 22
- 7c9f9f457e6641e3c093acff40bc8eac7c56d2c371bf
- [root@newhostname app]#
- rand : 表示生成随机数
- 20、22:表示生成的位数
- -base64:表示以base64的格式输出
- -hex: 便送hi以十六进制的格式输出
5、非对称秘钥加密
首先说几个算法:
RSA:支持公钥和数字签名的加密,密钥交换
ELGamal:支持公钥和数字签名的加密
DSA:支持数字签名,和密钥交换
DSS :支持密钥交换
dh:对称密钥交换
下面我们使用openssl生成私钥:
- [root@newhostname app]# openssl genrsa -out private_key
- Generating RSA private key, 2048 bit long modulus
- ......................+++
- .......+++
- e is 65537 (0x10001)
- genrsa :表示生成rsa
- -out :输出文件名
- 生成的默认位数为2048位,可以手工指定
- 使用rsa算法生成private_key
- 下面我们查看一下生成的key的内容
- [root@newhostname app]# ls
- fist.des3 fist_encrypt new_file private_key
- [root@newhostname app]# ll
- 总用量 16
- -rw-r--r--. 1 root root 57 1月 7 21:21 fist.des3
- -rw-r--r--. 1 root root 16 1月 6 19:44 fist_encrypt
- -rw-r--r--. 1 root root 16 1月 7 21:21 new_file
- -rw-r--r--. 1 root root 1679 1月 7 22:40 private_key
- [root@newhostname app]# cat private_key
- -----BEGIN RSA PRIVATE KEY-----
- MIIEpgIBAAKCAQEA3u6Q9YvkvAM0NZfZQb7NO3Mb8aw2Y0rNZtTA2tQ1Az90TM2r
- cu1QFfLeKphf1YUo2Lxq7SFHT07SCcdhzJolzzWGr+QjI8g5LAcWFYDFKj34lb+D
- Ps+LziqGoh8txsLzP1kitzVeuXB7ZMYlwRu0eJoOUeGdg3YXKNksDjgaQwS0+4vE
- xvu5xpVKTcpMwyHWAslb/LbNeR/x+M7m5nYZ7yPQ88CK+a2vmP/XOA53ezKOIDPc
- roT8jCTNYRJFhKjywyCi4tTFwtFBdoEubBoNH6Km+AiQ7oANf6vYKWQONn6Xid0u
- DIE2XUQ6V3bfgfRZAHWfEntToE/A4EuN5PopVQIDAQABAoIBAQCkKYFNkAqL+MAF
- hyBRLbPrx0QYnvwd+gNvadPqUMII9j0qIXnTU7XZs9KuAy7vCPOfRoBmxk7AtAYv
- dUcrZ4fYIk5gT9sgilyvczhr9Ts7dA8OFs0K/8KvutkRoWwQJZcCWx0ZVI/Adngn
- KVK79S7ccHWDDmTzXY6IYgPzJJUSK5FTtdhTsUetKSZZBwlrfq/2WmmqDbuGFU0H
- jxz4POT9n41nfuTZ8UmUkLmAWMnOi+3sDk/VC0uLDBMWwX26Sj1ngyBDOAZCCamm
- jOY2opEqQWrBMfXPMbZ1OrxaQ37EHRJkNqOlXOG/JB02Zw24i+Ac7qEduqL9Ye/J
- x7hQhc4xAoGBAO874TIFvxA4R2K+lintbcFKJyX7kzpHSclyCkWkymp8i5cSiaUr
- Yl/rYdNKJSWnId2dTvfZJ9dcw1GCMR/mEAE6stWNqVLySG8Izn00hogzu+ucokJC
- 2jFiRbNO9OyGrGOOzpuqpigOblwVCmLnELJeyVgsbDnaiwdgVpsnKXTjAoGBAO6O
- NeoPde8jqAAeZjhAfr2iqPVUCt5PDMd4CrC0+5ZaqEsoFRLeiUASpaScUIO3Y9IZ
- oN5HxzETgHj9ultuODtMzWnTwdYwzYHyLBQjxnykVtLErnnzLXqko4U40HnkzedV
- QDk+ZZ3kiubW7hEdX7uMcKRy3ZgmM3/qIuVqPvZnAoGBALU3+sJVsAGtYAXgsQdZ
- n0ZH0ZfoFgKTdcVu6XEP/3Tim
同样的可以通过man genrsa 来查看生成rsa的参数
因为私钥是一个很重要的文件,是绝对不允许泄露的,所以我们可以对访问的私钥加密,并设定权限,看如下操作
- [root@newhostname app]# (umask 066;openssl genrsa -out private_key.tmp -des3 2048)
- Generating RSA private key, 2048 bit long modulus
- ......................................................................+++
- .........................+++
- e is 65537 (0x10001)
- Enter pass phrase for private_key.tmp:
- Verifying - Enter pass phrase for private_key.tmp:
- [root@newhostname app]#
- ():表示在子shell中执行,不会影响当前环境,umask设定权限为066,创建文件时只有属主有读写权限
- -des3 :表示对生成的私钥进行对称加密, 使用了该选项,当调用私钥时需要输入密码才可以访问。
- 2048 表示生成的位数
- <br >我们查看一下私钥文件</br >
- [root@newhostname app]# cat private_key.tmp
- -----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,99D59E1B7B7E32C0
- jtPJ1f6naRCo3b0MybmUW0QrIMlh3rsnqX7429S3WaunFVERpIjfnxMERJ9pdqEL
- cbhh5w1ReUJfVsv9VBWffqKfQfiwklNIXvkE7W++K7bLT/LE6Q8Is0JKPciv7/NI
- sh/fCYEKsTmQxnnQY0U6wOg4jobBiK9iLO4gfhDhiVsWeKh1RlzxamOHYlMNFXog
- Eyl5KL4dfmHpVhDAOhSWVa/wr4dEjNANZ7+eMKP13T93fXUR1EMmPR4hneEMkiKs
- k0/7UouMgpe/pRpCJ04TD27ljGmN+IC7GEvannOiub6t73yH8qq9hTBr0g/qaAEi
- qSk3ecGX3zWQaGdrdI1Hjk+EgUaFr41FWP9fIixRPIgj+SzmTn8JNxWBrYRjPIgH
- v+3TqMvgP0sE9SCPxX+RqAq7+CK/+tBodNl1Hoj7DVT0bVfhielJtCh+HbOPQy1x
- CE9knOrJvPA+Q617aBRxnMRdO0ppLd1HMC1EJVst6tPfjJa+U7FCH6CcrvaT8IhJ
- Fd8Xd7gPYrJi6HHYXB1vWCKCRXHXLaAUqdsFasGL19sUI+T05jR8GimsI3ZRuBSt
- z/XkUuLFTAeRiz6bQOapWq7sCqOpSGFgi7QQbPy9gS4j9tAGVQCMYxupzWI7bJQV
- L6qoBe+qsHzjTPPihwIKJj1zIsVq5s3dm3ZMZv8D4sESJxKrtVT63bLLPp5juX2Q
- 1sqHr6wHqmQkqYSJ/fKZSG81FqV258tcCDvCkoc1EiV7FtRgwSz9gqaIZxx0EYVH
- W7kKyeL6iEGni6PB/LjZB5lGy/g1i6dggruk9VQ0sUyXmImvkYcdPMfl9sZg7QrL
- U16hUVRpGcH7pgelsyrJVUCAxkB7Q4Z78kVWesA02kzeAI0wdaebCYHYLOBFFxRF
- HAzTxYLal8CAXZ1gVihqOgjy1PlOHtB/cu+fDJLEJIiYMzGWd2LsgRd6kJqfwF1w
- s4xPJ6Lmzi816uLBvH01tXTqav4E/K8XQdBSMRHXPptwVE5nbu7XRNaCEpsNq6JP
- KY0uBfdkJj6ETZl/a/x1/LC0mYOB1I5IEinLy4vl0aGtBkIvzDqdNjt036stjFv5
- 0TVuka6WodxlJe57plfEg6gj+csBOPjn4IIs4Nc2qFESNFqQfFjmiPSLIh/gRe8+
- Lt7puWyohob//bP00Zq+xhFVMSRptQxAdQFWGRoxwv0ByfA2fWBjNAOA/UsYUj1X
- UZJFMfBCVKl6Q+4WL+lXyJmICKxVCgZMRCunk8Ydw9cQq4w5WJKZ/BnC9KAdPUWH
- DaLtjcIQUV3pEt2ippBj3YS17OFG5r/2NywAkT3YV6/WUo6bx/+vMl79Ld+1wPwS
- tZqtbLUSiGDnvN8kxU/XQWUdQXPdS0hwNZzSCwQZb+Llqp8iLc76xmQhE1aJ7Y0d
- w4pNSOKxQez48vZfQ8G/R+neu5gJydo5dMpLnuIbv4wfm2mzPO22wgESSsSJMj9C
- ZggZlHiOj3FXkp+pTThWu3aPi8gIPkjChoE5lGMz8xssaXg8ctBV4c4T1t5ZfzHZ
- xsQZV7TbIWOaglO/+fOof1xevkm7zXWWHfyYs6SZ/sI5lWf1N1MMqNdPr20Mr7p8
- -----END RSA PRIVATE KEY-----
- DEK-Info: DES-EDE3-CBC,99D59E1B7B7E32C0 这里显示私钥加过密,使用的是des3算法
从一个加过密的私钥中导出私钥
- [root@newhostname app]# openssl rsa -in private_key.tmp -out ok.tmp
- Enter pass phrase for private_key.tmp:
- writing RSA key
- [root@newhostname app]#
- 我们查看一下新生成文件
- [root@newhostname app]# cat ok.tmp
- -----BEGIN RSA PRIVATE KEY-----
- MIIEpQIBAAKCAQEA6QT8W214GlEmNwBnre9rnN5xVzjCnnBNO5rBxEiQUdzB5Gub
- Wuav2KYq5jC/5SBDSV0iRBHVOH+TTc7n4X3b470SER1kzki+3yPw00803xGeTWn7
- OeblPoejq4lzz+m4azFvVmbeWuyeoClh7S+qNcK1TNdd1u4GJr2BAcLEJbJzQoXo
- Fo+DdF7YE6vHnA/uSkkJFXsllslz8v6CVec88OFika78eNmqVW+DAUd2K5XQExaT
- jw+QpMzqgTZB+alXixmsUnEPjwEFKizKAsN3zpoeN+80mHONvHK/j5wMO/1U/WE+
- kWFMjBuoamD79vwZ1v0IKulMVg6ulyULZbA0JwIDAQABAoIBAChSyYzUw7ziIBfS
- hR6PWPL7d2edlegvDN5sqG1cFUVlS1RI3sh7NSDrmG7fLsXqsFoouL5Iy7oMMaR8
- Upot2nhthovZp1EfO5CHuqwGf+K+PMOuvF/HuhH5DPSpQ5ZOHrDGDDtKb94SJl0W
- 7DBMWEsXV6JlfoKsC/p2PrXcS28uPsFCNvmLcwxWfx/UpGLS07b0Wq3MB6plnPIh
- Ot+miuZyDwmaMar4jZUMQ9gSEznTExejeXI3c0tnLo5dvf/jO2gLMrYMo4p41SJt
- 6sCn0R/j4ZZmc0G5u6m3+Gas0G0JKCADmh++Yyoo6s9l/aRdKc/wF7KrQbnMfxI+
- p1rF4jECgYEA+VIL3+dbOiLq8ymXegUpSfKrOaII4//bWlZ+iLSoY+/8l6FTTfm0
- HfGnQcHSzLymGz5yyHk7IQjFlnQxXDA8e253rqz9wETeo2cX3xa0hZcjOS7w9p8t
- mPDkKLnZZd8p3kwli9DVZoUFnpd5wLsg6FdaXIh3tAuExNkxQ8K8cO8CgYEA70Mj
- uvH0R1YofXSAg1M+taNY4Xu8tsddiPg1u4jKIgzEnYedRcbmsVnJLsxV3ZoLP0y3
- F13Fry2i1Zt4avP+HDZ83SK49OHiSJZXRy/9esoqfzmGLylxt2i331jtT3uOqFlX
- GUVPIlpVVWngMA1cPTBoDoJvsJna6GS6QBlMAEkCgYEAh4zK9fXEDIyVbpTLTUTn
- GNQ9sXzeFo+xg6EI9Gw8LPF6RDoqn3dGLQ2IIOEvKa7bJG7EWyhGNISfYFhVychT
- 6cu6eBaHc3Q+E1rmiJzAku0D8oAJ9BvA36kAcv/wKUm2aqy9sRFeJHnn/zxdrqJO
- luN/NlXfttyYV6m59hw29bMCgYEAluX8QepZSyh+rujsKGc3FK2p38P/eDNyvXD1
- yonyGdl9o3Clcx2H33CmHrrGqNV/pHOIwdblV59rpFbCconhyP9gbsN4bRGNeoQ/
- FWmh73BTrxujklkMHEWSOe3G9asShQCbmxeIWj0oto7o0sWKWBkQd54yPOo8Evd8
- M/MAaOkCgYEA2e6hfcZqc6TPummLniUK5meT0xZbcth+Cf04XLyWP03wLl2MecKH
- HiiOyo+XJxH3fEAh0Wv4PPSOAdKMCU/beT5fOHsSInoP3gpFIofvl4p21YiRCPk1
- ARfAM6FKZ9/8WnNpdJhipt+0huS+p82tUMjX4cdOJdTm5w7iOO3npck=
- -----END RSA PRIVATE KEY-----
- 已经成功导出
从私钥中提取出公钥
- [root@newhostname app]# openssl rsa -in private_key -pubout -out pub_key
- writing RSA key
- [root@newhostname app]# ls
- fist.des3 fist_encrypt new_file private_key private_key.tmp pub_key
- [root@newhostname app]# cat pub_key
- -----BEGIN PUBLIC KEY-----
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3u6Q9YvkvAM0NZfZQb7N
- O3Mb8aw2Y0rNZtTA2tQ1Az90TM2rcu1QFfLeKphf1YUo2Lxq7SFHT07SCcdhzJol
- zzWGr+QjI8g5LAcWFYDFKj34lb+DPs+LziqGoh8txsLzP1kitzVeuXB7ZMYlwRu0
- eJoOUeGdg3YXKNksDjgaQwS0+4vExvu5xpVKTcpMwyHWAslb/LbNeR/x+M7m5nYZ
- 7yPQ88CK+a2vmP/XOA53ezKOIDPcroT8jCTNYRJFhKjywyCi4tTFwtFBdoEubBoN
- H6Km+AiQ7oANf6vYKWQONn6Xid0uDIE2XUQ6V3bfgfRZAHWfEntToE/A4EuN5Pop
- VQIDAQAB
- -----END PUBLIC KEY-----
- [root@newhostname app]#
- 注意:生成私钥使用的是 genrsa,而提取操作使用的是rsa
- -pubout :表示导出公钥 (必须加该选项,否则导出的是一个原本的私钥而不是公钥)
- in: 指定私钥
- out:输出公钥的文件名