前端初级加密学习

感谢王亚伟同志对本笔记RSA部分的支持。

都知道加密分为 对称加密非对称加密。 ###1.对称加密 这种加密方式原理非常简单

现有A,B两人有书信往来,为了避免信件在邮寄过程中被人偷拆查看内容,双方约定,信中所涉及到的数字,写的人要 +7 处理,看得人要 -7 处理。

现在A给B写信: 我家有6只老母鸡,4只小羊羔,来我家杀鸡宰羊款待你。 翻译过来就是: 我家有-1只老母鸡,-3只小羊羔,来我家杀鸡宰羊款待你。

那么B看到了信就领悟了精神:我家啥玩意没有,来了要自备干粮。

这个 “ + ” 就是算法(计算方法),这个“ 7 ”就是秘钥,“6”和“4”就是密文,“-1”和“-3”就是原文(我们习惯叫明文), “ +7 ” 过程的复杂度决定了这种对称加密的安全性,复杂度越高,安全性越高,复杂度越低,安全性越低。

其实我们常见的对称加密非常多,水浒传里的绿林黑话、发电报用的摩尔斯电码、盲人看书用的布莱叶盲文(大多数人认为这是编码,对于编码与加密的区别,移步闲聊编码与加密

常用的对称加密方式AES加密 首先,AES加密 = 算法 + 秘钥,也就是 “ + ” 和 “ 7 ”,只不过AES加密产出的算法和秘钥都比较复杂,很难通过在没有算法和秘钥的情况下由密文推理出明文。 但是,AES加密的算法是公开的,这和我们举的AB例子有本质区别,这就要求我们必须保证秘钥安全。

下面就是我们前后端http协议通信时,通过对数据AES加密,避免明文传输。 AES加密通信

但是我们知道,黑客会通过DNS劫持等方式截取我们http请求 http请求被劫持

算法和秘钥都被黑客拿到,所以,单纯的AES加密貌似没啥用处。 有人说写死在客户端,大哥,人家不会翻看你JS文件吗。

###2.非对称加密 非对称加密就比对称加密厉害多了,它的原理我找不出现实案例去模拟,索性直接说吧。

假设:A与B要进行通信, C想窥探通信内容

B自己产出4个东西,加密算法 + 解密算法 + 公钥 + 私钥 其中 加密算法 + 解密算法 + 公钥 都被公开, 所以A 和 C都能获得

A通过 加密算法 + 公钥 对信件明文进行加密,可以简化成 加密(公钥 ,明文) = 密文

B拿到密文,通过解密算法 + 私钥 对密文进行解密,可以简化成 解密(私钥 ,密文) = 明文

C拿到密文,由于没有秘钥,空有解密算法是不能得到明文的。 解密( XX ,密文) ≠不等于 明文

常用的非对称加密方式RSA加密 RSA加密方式就是上述的ABC案例加密方式,他的大致算法如下:

  1. 生成两个质数 p 和 q
  2. n = p × q
  3. φ(n) = (p - 1)×(q - 1)【欧拉函数】
  4. 公钥 = e

e的取值要求: ① 1< e < φ(n) 【且e为正整数】 ② e 与 φ(n) 互质

5.私钥 = d

d的取值要求: ① e × d ÷ φ(n) ........... 余 1

6.加密算法 = m^e^ ÷ n 得余数=> c 【其中m为明文,c为密文】 7.解密算法 = c^d^ ÷ n 得余数=> m 【其中m为明文,c为密文】

总之RSA的核心就是因式分解,简单说就是知道p 和 q就能破解密文,且n 是已知的 ,例如 n = 15, p和q就是 3,5 或者 5,3,很简单就破解了,但是 n = 33609608874827 你来算算 p 和 q? (答案是 24036583 × 1398269,摘自梅森素数)

以上纯属扯闲篇,以下为前后端的RSA加密交互 RSA动态获取公钥

RSA动态获取公钥被篡改

看到了吧,动态获取公钥是有问题的,黑客劫持公钥后,自己生成一对公钥私钥,把自己的公钥发送给客户端,客户端拿到黑客的公钥进行加密,黑客拿到密文就能用自己的秘钥解密。

为了防止拦截,一般公司的做法都是把公钥提前写死在客户端,用的时候直接加密就好了,不需要去服务端获取公钥,而且还少了一次http请求,提高了一丢丢性能。 不过问题又来了,中国有句古话 “外盗易挡,家贼难防”。 员工泄密

这种概率很小,但是肯定有,虽然可以定期的更换秘钥对,但是其一增加维护成本,其二,你常在河边走哪有不湿鞋。

那么终极法宝上场。 RSA 和 AES 配合使用 这个方案黑客最难攻破的就是服务端向客户端返回的密文 Y,因为他不能获得客户端的RSA秘钥,当然XSS攻击不在讨论之内。

RSA 和 AES 配合好处: 1.RSA消耗性能,但是保密性高,可以用做签名。 2.AES性能比RSA强很多,可以用于主内容的加密传输,当我们只加密用户密码看不出什么效果,但是传输文件的话,效果就会显露明显。

这个传输方案是模拟https的加密过程 https加密传输流程

https加密的是整个请求,而前后端加密的是主内容,也就是请求的body部分,这点分清。 这也说明为什么使用https的域名页面首次打开会很慢,原因就是初始化时需要进行签名加密。