加密算法分类:
对称加密
对称加密算法也就是加密和解密用相同的密钥。这种加密方式加密解密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。常见的有AES,DES等。
非对称加密
加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC等。
非对称加密原理介绍
非对称加密算法最根本的原理:利用信息的不对称性
比如小明只会加法,所以大强就问了。7+7=?
10个呢?
……、99个、999个
当这个数字很大很大的时候,比如9999个。小明基本就搞不定了。
而此时大强微微一笑10000x7-7 =69993
公钥密码算法安全的必要条件(非充分)是“由公钥不能反推出私钥”。
例子:
下面我们举个例子,当整个世界只会乘法和加减法,而不会除法时,我们便可以有如下的推导
小红(服务器)选择一个公式3x5=15
.将数字5
作为私钥。
将3x?=15
作为公钥发出去。
小明(客户端)想告诉小红一个数字(加密信息)9
.
他随手想到一个私钥7
,并根据公钥3x?=15
想到两个等式:
3x7=21
15x7+9=114
(15也就是3*?)
将私钥7
和加密信息9
隐藏,得到3x??=21
和 15x??+x=114
作为公钥发给小红(服务器)。
小红拿到公钥后,根据结合律可以方便的将15x??
替换为21x5
此处能理解么?理解不了也没关系。下面我会讲。
根据乘法结合律
15x??=(3x5)x??=(3x??)x5=21x5
(因为小红知道15就是3x5)
代入公钥15x??+x=114
此时就是21x5+x=114了。小红(服务器)拿到了加密信息9
.
如果此时有一个黑客小黑,他即得到了公钥。他也可以推到3*??=21
但是只要他不知道小红的私钥5
就无法获取到加密信息9
。
现在我们会除法了。所以不能用上面来处理公钥。于是一帮科学家找啊找啊。终于找到了一些完美的类似场景。比如:
- RSA--极大整数因数分解。极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。
- ECC(椭圆曲线加密)。这个我看了半天没看懂。但是基本原理无非是找到了会乘法不会除法的场景。也就是正向求值比较简单,但是逆向却是几乎不能完成的任务。在这个的基础上,科学家选取了一条曲线,并命名为secp256k1。这个算法为普通大众所熟知的原因是因为它被选为区块链内常用的加密算法之一。想研究的可以看一下:Secp256k1的wiki
可能会用到的加密算法
RSA一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
AES高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。
PBKDF2(Password-Based Key Derivation Function)是一个用来导出密钥的函数,常用于生成加密的密码。
它的基本原理是通过一个伪随机函数(例如HMAC函数),把明文和一个盐值作为输入参数,然后重复进行运算,并最终产生密钥。
网络通信面临的风险
(1) 窃听风险:黑客可以获知通信内容。
(2) 篡改风险:黑客可以修改通信内容。
(3) 冒充风险:黑客可以冒充他人身份参与通信。
网络通信加密(解决窃听)
原则:
客户端不持有密钥。
加密解密时间损耗要低
分析一下下面三种情况分别需要选取什么加密算法?
情况一:客户端传输简短重要信息给服务端,且服务端返回的信息不需加密的情况。
情况二:客户端传输复杂重要信息给服务端。
情况三:客户端传输重要信息给服务端,服务端返回的信息需加密的情况。
RSA+AES加密
客户端加密过程主要分为以下三个步骤:
客户端随机产生AES的密钥,并保存在内存中;
对重要信息进行AES加密;
通过使用RSA对AES密钥进行公钥加密。
服务端解密过程主要分为以下两个步骤:
对加密后的AES密钥进行RSA私钥解密,拿到密钥原文;
对加密后的重要信息进行AES解密,拿到原始内容。
经过上述步骤,情况二就完成了。但是如果服务器需要返回加密信息给客户端呢?也就是情况三怎么办?
用AES加密信息传回来,此时客户端的AES密码还在内存中,可以解密。
注意:base64加密类前后端必须保持一致。
HASH算法(解决篡改)
哈希函数,又称散列算法,是一种从任何一种数据中创建小的数字“指纹”的方法。
散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(或哈希值)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。
我们应该都接触过这个概念,我们常用的HashMap,就是利用Hash函数,根据key的Hash值尽量打散成均匀分布的下标,这样查询时可以根据下标快速定位到value。此处思考一下,为何重写类的equal()函数时,要重写hashCode函数?
SHA256是SHA-2下细分出的一种算法
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,属于SHA算法之一,是SHA-1的后继者。
说白了,哈希函数,又称散列算法,是一种从任何一种数据中创建小的数字“指纹”的方法。
Hash算法不是加密算法。什么意思呢?很多人把自己的密码hash一下。觉得这下安全了。但是你如何解密呢?所谓的加密必定对应着解密。如果你自己加密的信息自己都无法解密,那么这加密有何用出?
注意:hash可以通过字典或者彩虹表算出来,这也就是为何有快HASH、慢HASH这种说法了。
但是这个可以用来做什么呢?确保信息的完整性。
客户端跟服务器通信时,使用哈希算法和密钥对数据进行哈希得到数据的一个哈希值,然后将该哈希值和数据一块发送给对方,对方收到数据之后,对数据使用相同的哈希算法和密钥进行哈希得到哈希值,如果得到的哈希值和对方发过来的相同,那么就说明数据没有经过篡改。
然后有人就说了,我把内容改了后,重新生成一个HASH不就行了么?
借用JWT内的一个函数说明一下。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
其中最关键的就是secret。因为黑客不知道secret,所以就无法重新生成HASH。
JWT常用来作为Token传递,它可以保证数据的不可篡改。但是切记,不要放敏感信息在里面。因为它不具有保密性。
证书(解决冒充)
有一天,服务器突然收到客户端一条请求,要转账一个亿。我的天,小红感觉此时并不简单,赶紧问客户端小明这是啥情况。小明说我从来没有发过这个请求啊。原来这是小黑冒充小明,伪造了一个情况。
为了解决这个情况。小红与小明商量说,以后每封信上,都签上自己特有的签名,并带上相关内容的HASH值。这样别人就冒充不了了。
HASH值用来校验这封信是否有被篡改过。
签名类似于指纹,用来标示这封信是否真实来自于指纹上所指向的人。一般来说,签名的内容中会包含这封信的发件方地址等信息。
小红收到信件后第一时间通过内容的HASH值来校验信件的内容长度;通过签名来校验发件方地址和指纹信息是否匹配。只有全部匹配才继续用之前的密钥进行解密操作。
这些标明了身份信息等信息的签名,就是我们常说的证书。
更准确的说,服务器小红跟客户端小明这样提前约定好证书格式,就是所谓的自签名证书。 12306就是这个做法。自签名证书存在什么问题?它需要客户端提前把自签名证书下载下来才能使用。
HTTPS通信
以上问题都解决了。其实我们已经初步实现了一个https。只不过https采用了CA证书(类比于结婚证,就是有一个公证机构提供证书)将证书做成了一个证书链。这样客户端可以预埋CA证书,省下了下载自签名证书这一步。
经过以上讨论,我们可以得出结论:
https是相当安全的传输方式
但是,可能你问题又来了。我用Charles可以看到https的传输内容啊!(旁白:咋这么多问题呢?)
其实呢,这个就是所谓的中间人攻击。
中间人攻击(英语:Man-in-the-middle attack,缩写:MITM)在密码学和计算机安全领域中,是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。
Charles伪造了一个中间证书(我们抓包时安装证书就是为了这个。)让服务器跟客户端经过它的代理,并交换所接收到数据。
你要知道,如果黑客有能力在你手机上安装证书,并设置代理了。那黑客不就是你本人么。所以可以说:用户与我们的服务器通信是安全的。
那么我如果想Charles抓包也不能看到我们的信息该如何做?
这个问题换一下就是“如何解决中间人攻击”?
做客户端本地的证书校验。我们的https服务是有一个特定的证书的。你将这个证书放在本地。服务器传值时,如果看到证书不是这个,则拦截处理即可。
但是问题又来了。证书放在本地,要是服务器证书换了该怎么办?
做证书更新,那么我要是不想证书更新呢?可以做证书服务商校验。这个就是下一篇文章的内容了。