原文http://alblue.cn/articles/2020/06/22/1592816777326.html
base64
原理
base64是一种编码方式,将8字节的列拆散为6位的片段,每个片段能够表达【0-63】值索引指向的64个字符,而base64定义了64个字符.
因为Base64的编码只有6个bit即可表示,而正常的字符是使用8个bit表示, 8和6的最小公倍数是24,所以4个Base64字符可以表示3个标准的ascll字符;
[图片上传失败...(image-f7af20-1595036789693)]
案例
[图片上传失败...(image-1e4219-1595036789693)]
现在还有一点小问题,当转换到最后, 最后的字符不足3个字符咋办, 如果不足三个字符的话,我们直接在最后添加=号即可, 具体可以参考以下两个字符串转换案例:
[图片上传失败...(image-820372-1595036789693)]
base64仅能用于传输便利,并不能算一种加密方式。
go实现
go编码
输出结果
go解码
输出结果
分组加密ECB/CBC
加密一般分为对称加密(Symmetric Key Encryption)和非对称加密(Asymmetric Key Encryption)。
对称加密又分为分组加密和序列密码。
分组密码,也叫块加密(block cyphers),一次加密明文中的一个块。是将明文按一定的位长分组,明文组经过加密运算得到密文组,密文组经过解密运算(加密运算的逆运算),还原成明文组。
序列密码,也叫流加密(stream cyphers),一次加密明文中的一个位。是指利用少量的密钥(制乱元素)通过某种复杂的运算(密码算法)产生大量的伪随机位流,用于对明文位流的加密。
解密是指用同样的密钥和密码算法及与加密相同的伪随机位流,用以还原明文位流。
分组加密算法中,有ECB,CBC,CFB,OFB这几种算法模式。
ECB
ECB(Electronic Codebook,电码本)模式是分组密码的一种最基本的工作模式。在该模式下,待处理信息被分为大小合适的分组,然后分别对每一分组独立进行加密或解密处理。支持并行
CBC
这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。只能串行
DES/3DES/AES
DES全称为Data Encryption Standard,即数据加密标准,是一种使用[密钥加密]的块算法
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
DES
原理
DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
特点:
1.简单,有利于并行计算,误差不会被传送;
2.不能隐藏明文的模式;
repetitions in message may show in cipher text/在密文中出现明文消息的重复
3.可能对明文进行主动攻击;
加密消息块相互独立成为被攻击的弱点/weakness due to encrypted message blocks being independent
DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
- 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
- 第一组数据D1与初始化向量I异或**后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
- 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
- 之后的数据以此类推,得到Cn
- 按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程,步骤如下:
- 首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
- 将第一组数据进行解密后与初始化向量I进行异或**得到第一组明文D1(注意:一定是先解密再异或)
- 将第二组数据C2进行解密后与第一组密文数据进行异或**得到第二组数据D2
- 之后依此类推,得到Dn
- 按顺序连为D1D2D3......Dn即为解密结果。
go实现DES
3DES
原理
3DES,对称加密的一种,也称Triple DES,3DES为DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。为了兼容普通的DES,3DES并没有直接使用
[图片上传失败...(image-28abdb-1595036789693)]
当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通DES加密算法的兼容。
[图片上传失败...(image-f11f3e-1595036789693)]
go实现
对比DES,3DES只是换了NewTripleDESCipher。不过,需要注意的是,密钥长度必须24byte,否则直接返回错误
AES
原理
AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同,如下表所示:
AES | 密钥长度(32位比特字) | 分组长度(32位比特字) | 加密轮数 |
---|---|---|---|
AES-128 | 4 | 4 | 10 |
AES-192 | 6 | 4 | 12 |
AES-256 | 8 | 4 | 14 |
[图片上传失败...(image-8f611c-1595036789694)] |
go实现
PKCS5Padding和PKCS7Padding都是密钥的一种填充方式,即当密钥长度不足时的一种密钥填充方式。PKCS5Padding的填充方式为当密钥长度不足时,缺几位补几个0,eg.针对AES128,如果密钥为“1234567890”一共10位,缺6位,采用PKCS5Padding方式填充之后的密钥为“1234567890000000”,补了6个0.PKCS7Padding的填充方式为当密钥长度不足时,缺几位补几个几,eg.对于AES128,如果密钥为”1234567890”一共10位,缺6位,采用PKCS7Padding方式填充之后的密钥为“1234567890666666”。
sha
SHA是一系列的加密算法,有SHA-1、SHA-2、SHA-3三大类,而SHA-1已经被破解,SHA-3应用较少,目前应用广泛相对安全的是SHA-2算法,这也是本篇文章重点讲述的算法。
算法核心思想和特点
该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段密文,也可以简单的理解为取一串输入码,并把它们转化为长度较短、位数固定的输出序列即散列值的过程。
原理
主流程分三大模块:常量的初始化、信息预处理、使用到的逻辑运算。
常量的初始化:
这些常量的作用是和数据源进行计算,增加数据的加密性,那么同学可以想一下,如果常量是一些如:1,2,3之类的整数,是不是就没什么加密可言了,所以需要这些常量很复杂,生成的规则是:对自然数中前8个(或64个)质数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit。(在后面的映射的过程中会用到这些常量)
例如:,2的平方根的小数部分约为0.414213562373095048,然后0.414213562373095048≈6?16?1+a?16?2+0?16^?3+...
所以2的平方根的小数部分取前32bit就得到:0x6a09e667
信息预处理:
预处理分两部分,第一部分是附加填充比特,第二部分是附加长度。目的是让整个消息满足指定的结构,从而处理起来可以统一化,格式化,这个也是计算机的基本思维方式,就是把复杂的数据转化为特定的格式,化繁为简,“去伪存真”。
附加填充比特
在报文末尾进行填充,使报文长度在对512取模以后的余数是448。具体是:先补第一个比特为1,然后都补0,直到长度满足对512取模后余数是448。需要注意即使长度已经满足对512取模后余数是448,补位也必须要进行,这时要填充512个比特。所以,填充是至少补一位,最多补512位。
例如:“abc”补位的过程。
a,b,c对应的ASCII码分别是97,98,99,
对应的二进制编码为:01100001 01100010 01100011;
首先补一个“1” : 0110000101100010 01100011 1;
然后补423个“0”:01100001 01100010 01100011 10000000 00000000 … 00000000;
补位完成后的数据如下:
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
附加长度值
是将原始数据的长度信息补到已经进行了填充操作的消息后面(就是第一步预处理后的信息),SHA256用一个64位的数据来表示原始消息的长度。所以SHA256加密的原始信息长度最大是2^64。
用上面的消息“abc”来操作,3个字符,占用24个bit,在进行了补长度的操作以后,整个消息就变成:
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018
核心算法:
将原始数据分解成512-bit大小的块,例如消息M可以被分解为n个块,于是整个算法需要做的就是完成n次迭代,n次迭代的结果就是最终的哈希值,即256bit的数字摘要。
每次迭代进行的映射用Map(Hi?1)=Hi表示,摘要的初始值H0,经过第一个映射后,得到H1,即完成了第一次迭代,H1经过第二次映射得到H2,……,依次处理,最后得到Hn,Hn即为最终的256-bit消息摘要。
go实现
md5
MD5已不再适合用于加密,仅适用于字符串压缩。md5 和 sha1 都是被破解了的。sha1 还是上个世纪的作品。md5 的碰撞复杂度只有 2^20,sha1 的碰撞复杂度约 2^63。
原理
MD5算法的过程分为四步:处理原文,设置初始值,循环加工,拼接结果。
第一步:处理原文
第二步:设置初始值
第三步:循环加工
[图片上传失败...(image-14f0a8-1595036789694)]
第四步:拼接结果
这一步就很简单了,把循环加工最终产生的A,B,C,D四个值拼接在一起,转换成字符串即可。
结果是16位长度的字符串,这16位是从32位md5值来的。是将32位md5去掉前八位,去掉后八位得到的。
破解方式
彩虹表
如果将哈希后的密文比作一把锁,暴力破解的方法就是现场制作各种各样不同齿形的钥匙,再来尝试能否开锁,这样耗时无疑很长;我以前错误理解的“彩虹表”是事先制作好所有齿形的钥匙,全部拿过来尝试开锁,这样虽然省去了制作钥匙的时间,但是后来发现这些钥匙实在是太多了,没法全部带在身上。而真正的彩虹表,是将钥匙按照某种规律进行分组,每组钥匙中只需要带最有特点的一个,当发现某个“特征钥匙” 差一点就能开锁了,则当场对该钥匙进行简单的打磨,直到能开锁为止。这种方法是既省力又省时的.
哈希碰撞
哈希碰撞就是一种优化过算法,其基本原理就是把密码明文对应的MD5与你的MD5进行对比,因为经过一些优化,所以无论是时间上,还是空间都很很快,感兴趣的可以查一下王小云教授关于哈希碰撞的论文.
常用破解MD5方法
目前来说,破解MD5加密的最有效的方法就是 哈希碰撞+彩虹表+对应秘钥,一些网络黑客会在一些明文存储用户密码的网站上窃取信息,假如黑客有一亿条数据,因为都是真实用户所以经过哈希碰撞之后,你的密码被破译出来的几率就真的非常大了,那破译不出来的可能就是因为大小写和一些特殊符号,这就用到了彩虹表,最后就是你的秘钥,比如你是之前对用户的密码进行加盐,还是之后对MD5之后的字符串进行的特殊处理,只要对方知道你的秘钥,那么你密码被破译出来的几率就非常非常高了,所以我们说: 一个密码系统的安全性只在于密钥的保密性,而不在于算法的保密性.
go实现
实际使用
如何安全的储存密码
- 获取随机盐值,每个用户不同,比如uuid
- sha2(uuid+用户真实密码)
不要使用固定盐值,不要使用过短的盐值,不要使用md5/sha1进行加密
信息签名
为了保证参数不被串改,可以把明文按照指定规则进行哈希,服务端与客户端按照指定规则对签名后的指纹进行校验。一般使用sha2或者md5
信息压缩
在redis存储时,可能会对部分条件进行存储,但是redis的key不宜过长,可以对实际参数进行md5压缩。
参数加密
对于敏感参数,可以在前后端统一使用对称加密,如3DES/AES加密后转为base64进行通信。
参考
DES相关
https://blog.csdn.net/sgsgy5/article/details/83584042
https://www.cnblogs.com/yanzi-meng/p/9640578.html
https://www.jianshu.com/p/aac46b0cec38
https://blog.csdn.net/gulang03/article/details/81175854
AES相关
https://blog.csdn.net/qq_35128300/article/details/96452200
https://www.jianshu.com/p/3741458695d2
SHA
https://blog.csdn.net/u011583927/article/details/80905740
MD5
https://blog.csdn.net/sinat_27933301/article/details/79538169
密码存储
https://www.cnblogs.com/makai/p/11130703.html