一、散列(哈希)
1.简介
散列函数,又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。
将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理。
2.特点
- 对相同数据运算,结果相同
- 对不同数据运算,结果长度相同
- 运算单向不可逆
3.常用算法
- MD5
MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节,32个字符)的散列值(hash value),用于确保信息传输完整一致。 - SHA家族
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。
MD5使用比较频繁,但是如果只是简单使用MD5安全性较低,目前已有网站提供部分MD5破解,如https://www.cmd5.com。为了增加安全性,使用MD5时一般会在加密数据后加上某个随机值(就是所谓的加盐),然后再进行MD5运算。
HMAC,全称为“Hash Message Authentication Code”,中文名“散列消息鉴别码”,主要是利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。秘钥就是我们上述所说的‘盐’,使用HMAC会加大安全性,同时HMAC对所有散列算法都有效。
4.实际应用
哈希算法用途很多,比如用户密码加密、文件校验、数字签名和数据检索。
用户密码加密
这里提供一个用户密码加密的方案:采用HMAC+MD5的方式进行加密,每个用户对应一个KEY作为HMAC的秘钥,HMAC运算结果再加上服务器返回的时间戳进行MD5,最终得到的值在网络上进行传输。为了进一步提高安全性KEY可以每过一段时间更换一次。
获取KEY的时机:
- 注册时
- 登陆时本地没有KEY
- 登陆时本地有KEY,但是检测该账号更换了设备
服务器和客户端加密数据对比:
- 首先服务器存储的是HMAC(密码+KEY) = password,返回客户端的时间戳是timeInterval
- 服务器会计算2个值:MD5(password + timeInterval) = password_s1;MD5(password + (timeInterval - 60s)) = password_s2
- 客户端请求的密码数据是MD5( HMAC(密码 + KEY) + 时间戳) = password_app
- 服务器会对比password_app是否是password_s1和password_s2中的一个值,如果匹配到则密码校验成功
文件校验
MD5和SHA1都具有高度的离散性,哪怕是只修改一个字节值都会导致MD5或SHA1值“巨大”变化,从实践角度,不同信息具有相同MD5或SHA1码 的可能性非常低,通常认为是不可能的。
MD5 Hash算法的"数字指纹"特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法。
注:秒传就是利用文件校验原理,哈希值相同代表改文件已经存在服务器,造成一种秒传的假象。
数字签名
由于哈希算法的唯一性,可以利用数据的哈希值判断数据是否被篡改,以此实现数字签名。通常传递给服务器的哈希值是经过RSA加密的。
数据检索
对搜索关键字进行哈希,通过哈希值匹配文件的关键字哈希值,以此实现检索。
二、对称加密
1.简介
对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。
2.特点
- 计算量小
- 加密速度快、机密效率高
- 加密和解密使用相同秘钥,安全隐患大
3.常用算法
- DES
数据加密标准(英语:Data Encryption Standard,缩写为 DES)是一种对称密钥加密算法。
DES现在已经不是一种安全的加密方法,主要因为它使用的56位密钥过短。 - 3DES
三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为TDEA,Triple DEA),或称3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。 - AES
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是美国联邦政府采用的一种区块加密标准。
密码学中,分组(block)密码的工作模式(mode of operation)允许使用同一个分组密码密钥对多于一块的数据进行加密,并保证其安全性。分组密码自身只能加密长度等于密码分组长度的单块数据,若要加密变长数据,则数据必须先被划分为一些单独的密码块。通常而言,最后一块数据也需要使用合适填充方式将数据扩展到匹配密码块大小的长度。
工作模式通常应用于对称加密,这里主要介绍一下ECB和CBC两种工作模式。
电子密码本(ECB)
最简单的加密模式即为电子密码本(Electronic codebook,ECB)模式。需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。
ECB模式的缺点在于同样的明文块会被加密成相同的密文块;因此,它不能很好的隐藏数据模式。
下面的例子显示了ECB在密文中显示明文的模式的程度:该图像的一个位图版本(左图)通过ECB模式可能会被加密成中图,而非ECB模式通常会将其加密成右图。
密码块链接(CBC)
IBM发明了密码分组链接(CBC,Cipher-block chaining)模式。在CBC模式中,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。
CBC是最为常用的工作模式。它的主要缺点在于加密过程是串行的,无法被并行化,而且消息必须被填充到块大小的整数倍。
CBC模式在加密时,明文中的微小改变会导致其后的全部密文块发生改变,而在解密时,从两个邻接的密文块中即可得到一个明文块。因此,解密过程可以被并行化,而解密时,密文中一位的改变只会导致其对应的明文块完全改变和下一个明文块中对应位发生改变,不会影响到其它明文的内容。
三、非对称加密
公开密钥加密(英语:Public-key cryptography),也称为非对称加密(英语:asymmetric cryptography),是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;一个用作加密的时候,另一个则用作解密。使用其中一个密钥把明文加密后所得的密文,只能用相对应的另一个密钥才能解密得到原本的明文;由于加密和解密需要两个不同的密钥,故被称为非对称加密。
常见的公钥加密算法有:RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫尔曼密钥交换协议中的公钥加密算法、椭圆曲线加密算法(英语:Elliptic Curve Cryptography, ECC)。使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开秘钥加密算法,ElGamal是另一种常用的非对称加密算法。
1.RSA介绍
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
2.原理公式
m是明文,c是密文
e和n构成公钥
d和n构成私钥
3.RSA安全性
对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
4.RSA特点
相对于DES和其他对称算法,RSA要慢得多。一般RSA加密小量的数据
5.加密解密流程
- 如果使用公钥加密,就要使用私钥进行解密
- 如果使用私钥加密,就要使用公钥进行解密
实际使用中由于RSA的特点,一般是配合AES一起使用。
四、命令行加密解密指令
- MD5
//计算MD5散列结果
md5 -s "string"
//计算SHA1散列结果
echo -n "string" | openssl sha -sha1
//计算SHA256散列结果
echo -n "string" | openssl sha -sha256
//计算SHA 512散列结果
echo -n "string" | openssl sha -sha512
//计算HMAC MD5散列结果
echo -n "string" | openssl dgst -md5 -hmac "key"
//计算HMAC SHA1散列结果
echo -n "string" | openssl sha -sha1 -hmac "key"
//计算HMAC SHA256散列结果
echo -n "string" | openssl sha -sha256 -hmac "key"
//计算HMAC SHA512散列结果
echo -n "string" | openssl sha -sha512 -hmac "key"
//计算文件的SHA1散列结果
openssl sha -sha1 file.dat
//计算文件的SHA256散列结果
openssl sha -sha256 file.dat
//计算文件的SHA512散列结果
openssl sha -sha512 file.dat
- DES、AES
//加密过程是先加密,再base64编码
//解密过程是先base64解码,再解密
//DES(ECB)加密
echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
//DES(ECB)解密
echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
//DES(CBC)加密
echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
//DES(CBC)解密
echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
//AES(ECB)加密
echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
//AES(ECB)解密
echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
//AES(CBC)加密
echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
//AES(CBC)解密
echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
- RSA
//加密解密
//生成私钥,1024为秘钥长度,为了安全性目前推荐长度至少为2048位。
openssl genrsa -out private.pem 1024
//从私钥中提取公钥
openssl rsa -in private.pem -pubout -out public.pem
//利用公钥进行加密
openssl rsautl -encrypt -in plaintext.txt -inkey public.pem -pubin -out ciphertext.txt
//利用私钥对公钥加密的内容进行解密
openssl rsautl -decrypt -in ciphertext.txt -inkey private.pem -out dec.txt
//利用私钥进行加密:签名
openssl rsautl -sign -in plaintext.txt -inkey private.pem -out ciphertext.txt
//利用公钥对私钥加密的内容进行解密
openssl rsautl -verify -in ciphertext.txt -inkey public.pem -pubin -out plaintext.txt
//证书生成
//生成秘钥
openssl genrsa -out private.pem 1024
//通过秘钥生成请求文件,这里会要求输入一些信息
openssl req -new -key private.pem -out rsacert.csr
//生成证书,但是程序无法直接使用:3650是证书有效时长
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
//提取公钥文件
openssl x509 -outform der -in rsacert.crt -out rsacert.der
//提取私钥文件
openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt