Linux_22 加密和解密及OpenSSL
通信加密和解密
Linux Service and Security:
OpenSSL(ssl/tls)
OpenSSH(ssh)
bind(dns)
web(http):httpd(apache),php,marladb(mysql),LAMP,nginx(tengine,openresty),lnmp
file server:nfs,samba,ftp
dhcp,pxe
iptables
sudo,pam,nsswitch
OpenSSL
传输层协议:TCP,UDP,SCTP
port:进程地址,进程向内核注册使用某端口(独占)
同一主机上的进程间通信:IPC,message queue,shm,semerphor
不同主机上的进程间通信:socket
cip:port<--->sip:port
cip:55673<--->sip:80
监听模式:LISTEN(ip:port)
SSL:Secure Sockets Layer
http-->ssl-->https
安全的目标:
保密性:confidentlality
完整性:integrity
可用性:availability
攻击类型:
威胁保密性的攻击:窃听、通信量分析;
威胁完整性的攻击:更改、伪装、重放、否认
威胁可用性的攻击:拒绝服务(DoS、DDoS)
解决方案:
技术(加密和解密)、服务(用于抵御攻击的服务,也即是为了上述安全目标而特地设计的安全服务)
加密和解密:
传统加密方法:替代加密方法、置换加密方法
现代加密方法:现代块加密方法
服务:
认证机制
访问控制机制
密钥算法和协议:
对称加密
公钥加密
单向加密
认证协议
Linux系统:OpenSSL(ssl),GPG(pgp)
OpenSSL由三部分组成:
libencrypt库
libssl库
openssl多用途命令行工具
加密算法和协议:
对称加密:加密和解密使用同一个密钥;
DES:Data Encryption Standard
3DES:Triple DES;
AES:Advanced Encryption Standard;(128bits,256bits,384bits)
Blowfish
Twofish
IDEA
RC6
CAST5
特性:
1.加密、解密使用同一个密钥
2.将原始数据分割成为固定大小的块,诸葛进行加密;
缺陷:
1.密钥过多;
2.密钥分发困难;
公钥加密:密钥分为公钥与私钥
公钥:从私钥中提取产生;可供开给所有人;pubkey
私钥:通过工具创建,使用者自己留存,必须保证其私密性;secret key;
特点:用公钥加密的数据,只能使用与之配对儿的私钥解密;反之亦然;
用途:
数字签名:主要在于让接收方确认发送方的身份;发送方先用单向加密计算出数据的特征码,然后再用私钥加密特征码,加密后的特征码就叫数字签名;这样就能保证对方能验证自己的身份,也能保证对方接收数据的完整性,但数据的完整性无法保证。
密钥交换:发送方用对方公钥加密一个对称密钥,并发送给对方;
数据加密:
算法:RSA,DSA,ELGamal
DSS:Digital Signature Standard
DSA:Digital Signature Algorithm
单向加密:即提出数据指纹;之恶能加密,不能解密;
特性:定长输出、雪崩效应;
功能:完整性;
算法:
md5:Message Digest 5,128bits
sha1:Secure Hash Algorithm 1,160bits
sha224,sha256,sha384,sha512
密钥交换:IKE(Internet Key Exchange),RSA,DH(迪菲-赫尔曼),ECDH(椭圆曲线DH),ECDHE(临时椭圆曲线DH)
公钥加密
DH(Deffle-Hellman)
A:p,g
B:p,g
A:x
-->p^x%g==>B
A:(p^y%g)^x=p^yx%g
B:y
-->p^y%g==>A
B:(p^x%g)^y=p^xy%g
PKI:Public Key Infrastructure
公钥基础设施:
签证机构:CA
注册机构:RA
证书吊销列表:CRL
证书存取库:
X.509v3:定义了证书的结构以及认证协议标准
版本号
序列号
签名算法ID
发行者名称
有效期限
主体名称
主体公钥
发行者的唯一标识
扩展
发行者的签名
SSL:Secure sockets Layer
Netspace:1994
V1.0,V2.0(存在漏洞,被3.0取代),V3.0
SSL会话主要三步:
(1)客户端向服务器端索要并验证证书;
(2)双方协商生成“会话密钥”;
(3)双方采用“会话密钥”进行加密通信;
SSL handShake Protocol:
第一阶段:客户端向服务器端发送加密通信的请求,这个请求叫ClientHello
客户端在这一步通常要完成以下几个操作:
1.向服务器发送自己支持的协议版本;比如:tls1.2;
2.客户端生成一个随机数,稍后用户生成“会话密钥”;
3.支持的加密算法,比如AES,RSA;
4.支持的压缩算法;
第二阶段:服务器端回应客服端,叫做ServerHello
确认使用的加密通信协议版本,比如tls1.2;
服务器端生成一个随机数,稍后用于生成“会话密钥”;
确认使用的加密方法;
发送自己的服务器证书;
第三阶段:客户端收到服务器端的响应:
验证服务器证书,在确认无误后取出其公钥;(发证机构、证书完整性、证书持有者、证书有效期、吊销列表)
发送以下信息给服务器端:
一个随机数;(用于服务器公钥加密)
编码变更通知;(随后的通信都将使用双方协定的加密方法和密钥发送)
客户端握手结束通知;
第四阶段:
收到客户端发来的第三个随机数pre-master-key后,计算生成本次会话所用到的“会话密钥”;
向客户端发送如下信息:
编码变更通知,表示随后的细腻些都将用双方撒谎给你顶的加密方法和密钥发送;
服务端握手结束通知;
TLS:Transport Layer Security
IETF:1999
V1.0,V1.1(2006年发布),V1.2(2008年),V1.3(2014年,出现1.3草案,支持椭圆曲线算法)
分层设计:
1.最底层:基础算法原语的实现,aes,rsa,md5
2.向上一层:各种算法的实现;
3.再向上一层:组合算法实现的半成品;
4.用各种组件拼装而成的各种成品密码学协议软件;
协议的开源实现:OpenSSL
总结:身份认证是如何实现的?发送方用自己的私钥加密数据特征码,接收方用对方的公钥解密,说明这段解密数据是对方发的;什么是数字签名?身份认证当中就用到了数字签名(数字签名就是为了完成身份认证的),发送方用自己的私钥加密数据特征码的结果就叫做数字签名;密钥交换是如何实现的?我自己生成一段密钥,但是是用对方的公钥来加密这段密码,然后发送给对方。
加密和解密过程:
发送方(加密):先用单向加密计算要发送的数据的特征码,然后用自己的私钥加密这段特征码,并将结果附加到数据后面,生成一个临时的对称密钥,再用这个对称密钥加密整段数据,获取到对方(接收方)的公钥,并用对方的公钥加密上一步临时的对称密钥,并附加在整个数据的后面,然后发送给接收方。
接收方(解密):用自己的私钥去解密接收的数据,再用对称密钥解密整段加密的内容,用对方的公钥解密这段特征码,能解密的话,说明这段数据发送方的身份得到验证,然后再用同样的对称加密算法计算这段数据的特征码并与解密出来的进行比较,如果相同,数据完整性得到验证。否则,说明数据有问题。
OpenSSL
组件:
libcrypto,libssl主要由开发者使用;
openssl:多用途命令行工具;
openssl:
众多子命令,分为三类:
标准命令
消息摘要命令(dgst子命令)
加密命令(enc子命令)
标准命令:enc,ca,req,genrsa,...
对称加密:
工具:openssl enc,gpg
支持的算法:3des,aes,blowflsh,towflsh
enc命令:
openssl enc -e -des3 -a -salt -in fstab -out fstab.ciphertext # 加密
openssl enc -d -des3 -a -salt -in fstab.ciphertext -out fstab.plaintext # 解密
-e:表示加密
-a:表示在加解密之前使用base64进行编码和解码
-salt:use a salt in the key derivation routines. This is the default.
-in:表示指定输入的文件
-out:表示指定输出的文件
单向加密:
工具:openssl dgst,md5sum,sha1sum,sha224sum,...
dgst命令:
openssl dgst -md5 /PATH/TO/SOMEFILE
openssl dgst -md5 fstab.plaintext
md5sum fstab.plaintext # 两者计算的特征码相同
生成用户密码:
工具:passwd,openssl passwd
whatis passwd
sslpasswd (1ssl) - compute password hashes
passwd (1) - update user's authentication tokens
man sslpasswd
openssl passwd -1 -salt SALT
openssl passwd -1 -salt $(openssl rand -hex 4)
-1:Use the MD5 based BSD password algorithm 1.
openssl passwd -crypt -salt xx password prints xxj31ZMTZzkVA.
openssl passwd -1 -salt xxxxxxxx password prints $1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a..
openssl passwd -apr1 -salt xxxxxxxx password prints $apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0.
生成随机数
whatis rand
sslrand (1ssl) - generate pseudo-random bytes
man sslrand
openssl rand -base64 10 # base64的编码,保留10位
openssl rand -hex 10 # 16进制的编码
公钥加密:
加密解密:
算法:RSA,ELGamal
工具:openssl rsautl,gpg
数字签名:
算法:RSA,DSA,ELGamal
工具:
密钥交换:
算法:DH
生成密钥:
生成私钥:(umask 077;openssl genrsa -out /PATH/TO/PRIVATE_KEY_FILE NUM_BITS)
(umask 077;openssl genrsa -out /tmp/mykey3.private 2048)
提出公钥:公钥从私钥中提取
openssl rsa -in /PATH/FROM/PRIVATE_KEY -pubout
openssl rsa -in /tmp/mykey3.private -pubout
Linux系统上的随机数生成器:
/dev/random:仅从熵池返回随机数;随机数用尽,阻塞;
/dev/urandom:从熵池返回随机数;随机数用尽,会利用软件生成伪随机数,非阻塞;
伪随机数不安全;
熵池中随机数的来源:
硬盘IO中断时间间隔;
键盘IO中断事件间隔;
CA:
公共信任的CA,私有CA;
建立私有CA:
openssl
OpenCA
openssl命令:
配置文件:/etc/pki/tls/openssl.cnf
构建私有CA:
在确定配置为CA的服务上生成一个自签证书,并未CA提供所需要的目录及文件即可;
步骤:
(1)生成私钥;
# (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
(2)生成自签证书;
whatis req
man req
req - PKCS#10 certificate request and certificate generating utility.
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3650
-x509:生成自签格式证书,专用于创建私有CA时,就加上-x509
-new:表示生成新证书签署请求;
-key:生成请求时用到的私有文件路径;
-out:生成请求文件路径;如果自签操作将直接生成签署过的证书;
-days:指明证书的有效期为多少天,默认365天
(3)为CA提供所需所需的目录及文件
# mkdir -pv /etc/pki/CA/{certs,crl,newcerts}
# touch /etc/pki/CA/{serial,index.txt}
# echo 01 > /etc/pki/CA/serial
要用到证书进行安全通信的服务器,需要向CA请求签署证书;
步骤:(以httpd为例)
(1)用到证书的主机生成证书签署请求;
# mkdir /etc/httpd/ssl
# cd /etc/httpd/ssl
# (umask 077;openssl genrsa -out httpd.key 2048)
(2) 生成证书签署请求
# openssl req -new -key /etc/httpd/ssl/httpd.key -out /etc/httpdssl/httpd.csr -days 365
(3)将请求通过可靠方式发送给CA主机;
(4)在CA主机上签署证书;
# openssl ca -in /tmp/httpd.csr -out /etc/pki/CA/certs/httpd.crt -days 365
查看证书中的信息:
# openssl x509 -in /etc/pki/CA/certs/httpd.crt -noout -serial -subject # 在CA主机上的查看
吊销证书:
步骤(在CA上执行):
(1)客户端获取要吊销的证书的serial(在使用证书的主机上执行):
openssl x509 -in /etc/pki/CA/certs/httpd.crt -noout -serial -subject
(2)CA主机吊销证书
先根据客户提交的serial和subject信息,对比其与本机数据库inidex.txt中存储的是否一致;
吊销:
# openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem
其中的SERIAL要换成证书真正的序列号;
(3)生成吊销证书的吊销编号(第一次吊销证书时执行)
# echo 01 > /etc/pki/CA/crlnumber
(4)更新证书吊销列表
# openssl ca -gencrl -out thisca.crl
查看crl文件:
# openssl crl -in /PATH/FROM/CRL_FILE.crl -noout -text
注意:(1)(2)(3)在请求的主机上做,(4)在CA主机上做
生成公钥: