密码学前言:
网络数据传输威胁:
1、数据窃取
2、数据篡改
3、身份伪装
信息安全问题:
就是服务器和数据库被入侵(Hack)
1、在传输过程中
2、在存储过程中
那么如何解决这些问题呢?
密码学就可以解决这些问题,利用加密、解密算法,完美的保障用户的安全,达到高效信任的网络通 信。
密码学:
密码学是一种将数据加密处理,保障数据的安全,防止第三方或工众访问私人信息,可对数据进行加密解密。
加密算法 + 解密算法 = 密码学
密码学的核心是算法,算法的核心是密钥。
密码学 --> 算法 ---> 密钥
注意:密码学是通用的,加密解密和语言无关,什么需要都能进行加密解密,无非就是调用的api不同。
密码学分类:
编码解码
Base64编码表:
A~Z、a~z、0~9、+、/
Base64编码步骤:
1、将指定的数据对照ASCII码表,转为2进制,8位1组,不够高位补0
2、然后6位一组,最后一组不够长低位补0
3、计算出来6位一组的十进制作为下标对照base64表,
4、取出最终结果,四位一组,最后一组不够长补=
Base58编码表:
1~9、A~Z、a~z (不包含数字"0"、大写字母o"O"、小写字母L"l"、大写字母i "I")
注意:双引号里面的就是不包含的。
Base58步骤:
1、将数据对照ASCII码表,然后算出16进制
2、16进制的每一位按权展开,然后相加,求出总和
3、总和%58,直到余数<= 57
4、从上往下取出余数,作为下标对照base58表,得出结果
5、结果反转,得出最终结果
hash算法
hash算法是将不定长的字符串,计算成长度固定,不可逆的杂凑字符串。他是单向散列算法,就是结果不可逆推具有唯一性。如果数据不需要进行还原,只用于快速校验,选择hash是很好的选择。
hash特点:
正向快速:可以短时间快速计算出hash结果值
逆向困难:就是计算出来的hash结果值不可在短时间内计算出元数据
输入敏感:就是输入的数据稍微有一点偏差,计算出来的hash值都是千差万别的
强抗碰撞性:不同的输入很难产生相同的输出hash值,结果唯一性。
Hash分类:
MD4、MD5(长度128位,但是不安全,已经被破解了
SHA1(长度160位,也不安全,被破解了)
SHA2系列:SHA224,、SHA256(长度256位,32字节,安全)、SHA384、SHA512
SHA3系列:又名Keccak算法,以太坊系统就是用的这个算法
拓展:比特币系统用的是sha256算法,以太坊系统用的就是Keccak算法
异或运算:算出两数二进制,然后进行比较,相同为0,不同为1
位运算:转为二进制,然后<< ,高位舍弃,低位补0;>> 低位舍弃,高位补0,
&:全0位0,全1为1。
|:有1位1,全0为0。
^:相同为0,不同为1。
sha256计算过程
1、附加填充比特,直到最后长度满足448 , 长度%512 = 448、最后面先补1个1,后面的全部补0
2、附加长度值,补64bit, 补到512位,就是把长度值添加到结果的后面(如果元数据的长度是8,那么前面就 补58个0)。
3、初始化缓存
512/32 = 16(说明有16个16进制)
A ~ H
质数:2,3,5,7,11,13,17,19....
进行平方根
取小数位的前32位,转换为16进制的值,作为256bit缓存值,当作结果。
4、计算,处理512bit的报文序列
通过& ^ | 等进行运算,一直推算,压缩成32字节的最终结果
注意:步骤3和步骤4非常的复杂 ,这里说的不是很正确和完整。
hash和加密区别:
hash:单向散列函数,逆向困难,长度固定,(仅验证,不还原)
加密:只要知道密钥结果可推算回来,可逆,长度不一致,(加密解密,还原数据)
原则:
如果仅用于比较验证,后期不需要 进行还原数据,那么就使用hash算法,
如果被保护的数据需要进行还原,则使用加密
分组加密
分组加密是指将指定的明文数据按固定长度分组之后进行加密处理。
注意:不管是对称还是非对称算法都需要先进行分组,然后和密钥进行运算。这样也能提高效率。
一次性密码本没有进行分组处理
明文数据按照多少位进行分组依赖于密钥长度。
分组模式 == 加密模式
ECB(电子密码本)
特点:相同的明文永远加密成相同长度的密文
缺点:不安全,可以进行频率分析攻击,根据密文和明文出现的频率,判断出原始数据,风险高
CBC(密文分组链接模式)
特点:先异或,后加密
第二步加密就是真正的 算法,核心
运算特点:当前加密的数据依赖于上一个分组产生的密文结果
密钥流:依赖上一个分组产生的密文
缺陷:
链式加密,其中只要有一个分组出现问题,后面的不能正常运行。
无法对中间分组数据单独进行加密
运算过程:
分组1和向量IV进行异或运算 ---> 然后进行加密,得到密文1 --->密文1 和下一组明文数据2进行异或 ---> 然后进行加密 ---> 得到密文2 ---> 密文2和明文数据组3进行异或 ---> 然后进行加密 --->得到密文3 ---> 一直重复上面步骤
CFB(密文反馈模式)
特点:先加密,后异或
分组1和谁进行异或:当然是加密后的初识向量IV
密钥流:就是每一次生成的密钥都不一样,依赖密文加密后得到密钥
总结:上一组的输出作为下一组的输入,再进行异或
运算步骤:
初识IV进行加密 ---> 然后和明文分组1进行异或 ---> 得到输出密文1 ---> 密文1作为输入进行加密 ---> 和明文分组2进行异或 ---> 得到密文2 ---> 密文2进行加密 ---> 和明文分组3进行异或 ---> 得到密文4 ......
OFB(输出反馈模式)
就是一直对向量IV进行加密
运算步骤:
向量IV进行加密 ---> 然后和明文分组1进行异或运算 ---> 得到密文分组1 ---> 加密后的向量IV再次加密 ---> 和明文分组2进行异或 ---> 得到密文分组2 ---> 加密后的IV再次加密 ---> 和明文分组3进行异或 ---> 得到密文3 .......
OFB和CFB的区别:密钥的生成方式不一样。
CTR(计数器模式)
就是一直对计数器加密,然后实现异或,计数器是自增的
密钥流:依赖加密后的计算器
运算过程:
先对明文进行分组,每一次分组都会产生1个逐次累加的计数器 ---> 计数器进行加密 ---> 和明文分组1进行异或 ---> 得到密文1 ----> 分组2对应的计算器加密 ----> 和明文分组2进行异或 ---> 得到密文2 ---> 计数器3 进行加密 ---> 和明文分组3进行异或 ----> 得到密文3 .....
注意:上述说的密钥流都是基于异或运算前的输入数据。
注意:由于CBC每一次运算都会产生一个子密钥,但是密钥 流不是密钥,而是上一个分组的加密后的密文,然后进行异或运算,所以,CBC模式不存在最终的密钥。
注意:每一次分组的最后一组都不会是等于够分组长度,所以我们要进行补码,也就是填充。
填充模式 == 补码
计算补码值:分组长度 - (明文长度%分组长度)
blockSize - len(cipherText) % blockSize
PKCS5填充
每一个填充的字节都纪录了填充的字节数
"a" 填充后结果:[97 7 7 7 7 7 7 7] (8 - 1%8 = 7 个7)
"ab" 填充结果为:[97 98 6 6 6 6 6 6 ] (8 - 2 %8 = 6个6)
Zeros填充
也叫0填充,全部填充为0的字节
"a" 填充结果为:[97 0 0 0 0 0 0 0 ] (8 - 1 %8 = 7个0)
"ab" 填充结果为:[97 98 0 0 0 0 0 0 ] (8 - 2 %8 = 6个0)
注意:我们计算补码值都是按照字节来计算的,就是分组长度也转为了byte[] ,明文长度也是字节表示
拓展:
Go语言填充补码函数:bytes.Repeat(填充的字节,填充的)
对称加密
对称加密优点:
计算量小,加密速度快,加密效率高。
注意:计算量小是指每次数据进行分组的长度不能太大,然后进行计算。
对称加密缺点:
密钥key安全问题没有得到保障。
对称加密三要素:
1.明文:原数据
2.密钥 :双方约定的钥匙,会根据算法的不同长度不同
3.加密算法:以什么方式进行加密,常用的有(des,3des,Aes,rc)
对称解密三要素:
1.密文:加密后的没铭文数据
2.密钥:一定要一样
3.解密算法:可能要和加密的相同,也可能异同(例如凯撒尔密码)
对称加密代表:
一次性密码本:
特点:
密钥的长度必须和明文数据的长度一样,密钥不能重复使用。
缺点:
不能进行分组处理,明文数据太长密钥就也要过长,这样计算的复杂度就越高,效率就低。
实现过程:
先产生一个和明文长度一致的真随机比特序列 ----> 明文和密钥进行异或运算 ---> 得到密文
面临问题:
密钥重用问题:密钥不能重复使用
密钥传输问题:如何将密钥安全的发送
密钥保存问题:密文多,密钥就多,资源占用大
密钥同步问题:明文过长,密钥就需要同等的长度
密钥生成问题:困难,因为真随机数,计算量大
DES:
密钥长度:64位 8字节
有效密钥:56位 (8位去做奇偶校验)
分组长度:64位
des算法入口参数:
Key:密钥(8个字节共64位)
Date:数据
Mode:为Des的工作方式,加密或者解密
运算过程:
①将64位分为左右两部分 ---> 右边32位进行加入轮函数进行运算 ---> 得到子密钥 ---> 子密钥和左边进行异或运算 ---> 得到左边的密文
②左右换位置 ---> 右边(原左边)进行轮函数运算 ----> 得到子密钥 ---> 和左边的(原右边) 进行异或运算 ---> 得到右边32位的密文。
注意:一共要进行16轮运算
代码实现步骤:
分组、补码、模式、工作模式、表现形式加密
des.NewCipher()详解:
1.创建加密块对象,把密钥传入当作初始密钥
2.利用8byte[] 字节的密钥进行轮运算,产生16个56bit位别的有效子密钥。
3DES
密钥长度:64位,8字节
有效位数:56位
分组长度:64位
3des算法入口参数:
Key:密钥(24个字节共192位)
Date:数据
Mode:为Des的工作方式,加密或者解密
实现过程:
其实就是每一轮进行3次des运算,24字节的密钥要分割成3组。
DES和3DES的相同点和区别:
相同点:
有效密钥数是一样的,都是56bit
总轮数相同,都是16轮
每次运算的密钥长度是一样的。
区别:
des的入口参数密钥长度:8byte[] ,64bit
3des 的入口参数密钥长度:24byte[] , 192bit
des有效密钥:56位
3des总有效密钥:168位
des.NewTripleDESCipher()详解:
1.24字节密钥传入,创建加密块对象,
2.对初始密钥进行分割,形成3个8byte字节的密钥
3.利用8字节的密钥产生16个56位的有效子密钥(1轮产生16个),3des总子密钥:16*3个
注意:这里说的每一轮3次des,其实是加密、解密、加密,
AES
密钥长度:
16字节128bit (10轮)
24字节192bit (12轮)
32字节256bit (14轮)
运算过程:
1.字节替换 2.行移位 3.混合列 4.异或运算
轮运算:就是那个计算过程需要迭代几次。
aes.NewCBCEncrypter() 详解:
1.创建加密块block对象
2.判断密钥长度是否符合,符合确定轮数(16byte == 10轮,24byte == 12轮,32byte == 14轮)
3.符合进行轮运算
注意:AES是使用最为广泛的加密算法,而且他的安全性很好,效率也高。
每一轮出现的子密钥都是单独的,因为是CBC分组模式,所以不存在总子密钥,他不是密钥流。
RC
是不公开的对称加密算法。
注意:对称加密的密钥需要双方提前商议好,而且密钥需要进行传输交互,这个传输的过程就很危险,所以,对称加密面临 “key安全问题”。所以有了非对称加密。
非对称加密
公钥加密,私钥解密 --- 非对称加密
私钥签名,公钥验签 --- 数字签名
就是每个人都有两把钥匙,公钥和私钥
公钥:公开的
私钥:严格保密
非对称分类:
RSA
RSA是基于大质数理论,其本质是质因数分解
密钥长度:
512bit (rsa最低要求)
1024bit
2048bit
4096bit
实现过程:
1、首先在一台设备上生成密钥对,
2、然后把公钥发送给发送者
3、发送者使用公钥进行加密,得到密文
4、然后 发送者将密文发送给 接收者,
5、接收者使用私钥进行对密文解密 ,得到明文数据
注意:这个过程私钥始终没有在 网络上进行传输,只是传输了密文和公钥,所以,非对称加密的私钥 要严格保存,然后这个过程也是非常安全的 。
RSA算法过程:
1、选择两个不相等的质数,(p,q)
2、取p,q的乘积N
3、计算p-1 和q-1的乘积temp,空集φ。
4、随机选择一个整数E,0< E<temp
5、计算E的模反元素D,公式为:E*D %N = 1;注意:D是需要进行推算的,1开始推算
例如:
E * D % temp =1
3 * 1 % 20 = 3
3 * 2 % 20 = 6
….
3 * 7 %20 = 1
6、公钥是(N,E),私钥是(N,D)
密文 = 明文^E % N (N就是乘积的值)
明文 = 密文^D % N (D是计算出的模反元素)
代码实现:
一:生成pem证书文件
生成privateKey.pem + pubicKey.pem,保存在本地
二:加密解密
解析证书 文件 ,读取到privateKey + publicKey
加密:传入公钥pub 、数据data ,返回密文
解密:传入私钥pri、密文cipherText,返回明文
签名:传入私钥pri,明文的数据摘要dataHash(32字节),返回签名数据signText
验签:传入公钥pub,数据摘要dataHash,签名数据SignText
der格式:类型字段 + 长度字段 + 值字段 + 结束字段
der : type + length + value + end
注意:这里的验签就是将原文数据和签名数据一起发送了,然后收方使用公钥验签得到数字摘要datahash1,然后然后接受者再使用hash算法对原文hash计算得到数字摘要2,然后比对数字1和数字摘要2,看是否一致。
DSA
数据签名算法,只用作签名
椭圆曲线加密算法
ECC
是基于椭圆曲线理论,他是计算很多的交点,然后只会随机选择一个点作为私钥。
密钥长度:
106bit
132bit
160bit 20字节
椭圆曲线要求:
k这个线不能是奇异的光滑的,必须要有曲率。
点和点必须对称,就是这个曲线必须是对称的,复元
算法过程:
1、计算负元
2、通过该负元通过取模公式得到逆元
3、计算曲率K
4、计算出x的点, 公式为:x = K^2 - x1 - x2 mod 23
5、计算y的点, 公式为:y = k(x1 - x) - y1 mod 23
注意:23就是有限域
ECC相比于RSA具有很多的 优势,他们是竞争关系,但是ecc相对复杂。
ECC和RSA的对比:
ECC密钥长度比RSA短,所以速度更快
但是安全性是rsa的10倍
效率也一样
ecc占用的带宽比rsa小,存储空间也小
注意:ECC的安全基于算法,并不是基于密钥长度。
ECDSA
是ECC系列的分支,他主要用于私钥签名,公钥验签,
密钥长度:256位,32字节
ECDSA签名验签思路: 1、生成密钥对,返回私钥和公钥 2、sha256算法加密原文数据,返回32字节的数字摘要 3、然后传入私钥和数字摘要进行签名,得出r 和 s 的值 4、把公钥,数字摘要,r 和 s 的值传入验签,验签结果为true为验签成功
对称和非对称加密算法的区别:
对称加密:
密钥相同,只有一个
计算效率高
交互需要传输密钥
加密强度低,不安全
代表算法:DES、3DES、AES、RC
非对称加密:
密钥不同,至少两个
计算效率没有对称加密高
交互不需要传输密钥
加密强度非常高,安全
代表算法:RSA、DSA、ECC、ECDSA
数字签名
数字签名作用:
保证数据来源的合法性
保证数据的正确性
数字签名流程:
(签名)
发送方使用hash算法对原文进行hash计算,得到数字摘要
发送方使用私钥对数字摘要进行签名,得到签名数据
发送发将原文和签名数据一起发送
(验签)
接收方使用公钥对数字签名数据进行验签得到数字摘要1(消息来源的合法性)
接收方对原文进行hash计算,得到数字摘要2
比对数字摘要1 和 数字摘要2是否相等,一致的话就合法,不一致说明数据在中途被篡改,不安全(消息的正确性)
数字签名满足的要求:
签名不可伪造(私钥生成的),
签名不可抵赖(私钥盖章)
签名不可篡改(hash,元数据不能篡改)
签名不可复制(签名和原文是不可分割的整体)
签名的识别相对容易,任何人都能验证签名的有效性。(公钥验签,一对多)
https认证过程:
核心:
公钥(加密)
私钥(解密)
过程:
client通过https发送请求给 ---> Server --->返回证书(公钥)给客户端 ---> 检查证书合法性---->生成随机数 --->(用来当作密钥) ---> 使用密钥对数据加密(对称加密)--->
使用公钥对密钥进行加密 ---> 将加密后的密钥与数据发送到server ---> 使用自己的私钥解密密钥 ---> 使用解密后的密钥解密数据
拓展:
CA:证书认证颁发机构
x509:是证书文件的规范格式,一般用来作为证书文件的规范标准。
.pem文件:就是一个x509标准的数字证书,里面存储用户的私钥和公钥等。
PKCS:是公开加密标准,一般会用于公钥的格式化输出。
Der格式:就是ASN.1对象标准的编码格式。
ASN.1:是一种标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。
公式
求模公式:A % B = A-(A/B) * B
求补码值:分组长度 - 明文长度%分组长度