专注于Java领域优质技术号,欢迎关注
作者:肥朝
内容大纲.png
目的
面试很多时候都会问一些通用的东西,比如多线程,比如数据加密,比如HTTPS,换句话说,无论你从事前端还是后端,数据加密和HTTPS都是必须掌握的
数据加密
首先,我们为什么要数据加密?因为HTTP所有访问都是明文的,只要能监听到网络所有的请求数据都是透明的,比如任何浏览器的开发者工具就能很清楚的看到表单提交的参数和地址,在Android和iOS中也经常通过抓包的方式高仿其他的APP,比如Charles就是Mac上常用的抓包工具
表单加密传输
由于篇幅有限,这里就暂时拿JS举例
比如我们平时使用的JS插件,凡是.min结尾的,里面的代码都是混乱的,如图:
这些JS都是经过压缩的,他就是把注释和空格去掉,把变量名变成短变量名,使得我们阅读起来就很困难了.
其实目前没有绝对的安全,因为安全本来就是一场攻防战,我们能做的,只能是加大解密的成本来防止解密,例如我们可以使用JS混淆,如图:
从这里就可以看出,一段简单的代码加密压缩后就变得如此复杂.但是细心的同学就发现,旁边还有个解密的按钮呢,所以这种方式的缺陷就在于,这种加密方式是可逆的,一旦得到了加密的JS,就能解密
对称加密算法
此时回忆一下,我们之前是怎么加密的?我们都是前台根据一定规则加密,后台又根据这个规则解密.那么我们有没有办法做得更安全一点?
办法是有的,比如我们加密的时候,向后台请求一个随机数,而这个随机数,就作为前台加密和后台解密的钥匙,我们把这个,称之为密钥
我们用一张图来描述一下这个过程:
从序号3我们知道,只要拿不到随机数(密钥),那么将无法解密,但是万一别人就是能拿到呢?所以,这个对称加密最大的难点就在于,怎么有效的隐藏密钥,以及后台怎么管理这个密钥池
非对称加密算法
非对称加密算法是我们平时用的最多的,那么什么是非对称加密算法呢?
我们这么设想,有没有一种算法加密过后,用逆向的解密是解不出来的?也就是比如原来的密码是123,我们的加密算法是每一位+1,也就是变成了234,然后得到234后,我们每一位减一却得不到123,而是需要另一种算法才能算出123
从上面这个例子我们知道,这个加密算法和解密算法完全就是两码事,这种加密的思想,就是非对称加密算法的一种方式
另一种方式,也就是我们用得最多的,其中这个非对称,就体现在钥匙上面,之前我们的对称加密算法,缺陷就是,前台和后台拿到的钥匙是一样的
非对称加密算法采用公钥/私钥的方式,使用加密算法(明文,公钥)生成密文,这个密文,就算知道了公钥和加密算法,也没办法解密,必须要这个公钥对应的私钥才能解密.
也就是说,公钥加密的,只能靠私钥解密.私钥加密的,也只能靠公钥解密,所以我们的公钥可以随意向外公布,只需要隐藏好私钥即可,具体实现如图
所以,这种加密算法的缺陷在于,只要拿到了私钥,所有的密文都能解开
非对称加密算法中,RSA加密算法用得也比较多,RSA是由创建者的名字首字母组成的,由于篇幅有限,这里不过多介绍.
HTTPS
HTTPS简单介绍
HTTPS相信大家都不会陌生,那么怎么认识HTTPS呢,我们从三个方面入手,也就是是什么,有什么用,为什么需要
是什么:
HTTPS是一种网络协议,他是处于HTTP协议和TCP/IP协议之间的一个协议(如图),所以,HTTPS其实不是我们写代码的时候需要处理的东西,他是browser和应用服务器(例如Tomcat)需要去处理的一个东西.但是,如果你是做Android或者iOS客户端,要发送和处理一个HTTPS请求的时候,也需要做额外的处理
有什么用:
能够让浏览器明确访问的网站是安全网站一旦HTTPS连接成功,浏览器和服务器之间的数据传输全部是加密传输(对称加密)
为什么需要
HTTP上传输的所有数据都是明文,于是出现了SSL(Secure Sockets Layer安全套接字层)协议用于对HTTP协议进行加密传输, HTTP + SSL = HTTPS;IETF对SSL进行了升级,就是TLS(Transport Layer Security),其实我们现在说的HTTPS都是使用的是TLS;
HTTPS的工作原理
假设我们访问,这之间的握手协议如下图
HTTPS的工作原理.png
文字解读:
- 浏览器(客户端)将自己支持的一套加密规则(SSL版本号,加密算法版本,哈希算法版本)发送给网站,网站接收到浏览器支持的算法版本,选择一组对应的算法版本
- 网站把网站地址,加密公钥,证书颁发结构等信息以SSL证书的形式发送给客户端
- 客户端接收网站发送的证书后,需要验证该证书的合法性:从底层的SSL证书向上层证书进行验证,只要在证书链中任意一级证书是可信的,那么这个证书是可信的
- 得到SSL证书中的域名,和当前访问网站进行比对,比对通过,浏览器信任该站点
- 浏览器生成一个随机数:random,并使用证书中的公钥进行加密(非对称算法),伪代码如:RSA(SSL证书中的公钥,random)->密文A
- 浏览器生成一个握手信息,如:"toby", 并使用确定的HASH算法生成一个hash值,伪代码如:HASH("toby")->hash码
- 使用random对toby握手信息进行加密(对称算法),伪代码如:encore(random,"toby")->密文B
- 把密文A,hash码,密文B全部传给网站
- 服务器接收到密文A、hash码、密文B后,使用服务器端SSL证书中的密钥对密文A进行解密,伪代码如:RSA(SSL证书中的密钥,密文A)->random
- 使用加密算法对密文B进行解密,伪代码如decode(random,密文B)->握手信息
- 再用hash算法算出握手信息的hash值,伪代码如HASH(握手信息)->hash码
- 对比这个hash码和传过来的hash码是否一致,如果一致,服务器端再生成一个握手信息比如"hello"对服务器端的一个握手信息进行加密,伪代码如encode(random,"hello")->密文
- 对握手信息进行hash计算,伪代码如hash("hello")->hash码
- 把hash码和密文传给浏览器
- 客户端接收到密文和hash码
- decode(random,密文)->握手信息
- HASH(握手信息)->hash码
- 对比hash码,如果一致,随机码都互相验证过,并且都各自存放好了,此时,两边都完成了HTTP交互,现在的结果是,客户端和服务器都有一个random
接下来的请求就全部使用encode(random,明文)进行加密传输了,服务器端则使用decode(random,密文)->明文,此时,这个加密算法就是一个对称加密算法了,这个解析出来的明文就会交给HTTP协议,所以我们应用拿到的是明文
线上充值原理
首先这里有三个名词,一个是xx平台就是我们要充值的平台,还有一个是第三方支付平台,这样的平台有很多,比如大家都知道的支付宝,财付通,网银在线等等,还有一个是银行,这个大家都懂
我一向是都是喜欢先粗暴地上流程图,如下:
文字解读:
首先,xx平台需要和第三方平台签订协议,这样xx平台就能得到一个在第三方平台的账户,那么我们开始充值流程
1.用户开始在xx平台进行充值
2.用户由xx平台的在线充值界面跳转到第三方支付平台,这个时候需要带上username、password、apikey以便第三方平台知道我们来自哪个平台,同时还要带上一个唯一的id作为交易流水
3.一般有快速支付和网银支付,这里拿网银支付举例,当点击网银支付的时候,跳转到银行的转账界面,这个时候要注意,这个接口是银行和第三方支付平台对接的,所以跳转的时候还要带上平台的唯一标识
4.我们假设转账成功,那么这个时候,钱是转到了第三方支付平台,而不是xx平台
5.第三方平台需要为银行提供一个接口,进行回调,告诉第三方支付平台,流水号的处理结果
6.这个时候,将充值金额累加到xx平台的账户中,但是这个只是虚拟现金流的增加,钱还在第三方支付平台的银行账户中
7.xx平台需要为第三方平台提供一个接口,处理回调,告诉xx平台,流水号的处理结果
8.假设回调成功状态,xx平台将在用户的账户把钱增加,但是这个时候,也只是虚拟现金流的增加,此时钱还是在第三方支付平台的账户
9.第三方支付平台会在一个结算周期(一般是两天到三天),他会自动地把这段时间之内交易成功的钱打到xx平台上
所有第三方支付平台的原理都是以上流程,所以,对于我们xx平台而言,只需要做两件事
- 页面跳转,把充值信息告诉第三方支付平台
- 写一个回调的接口,接收交易情况
来源:https://www.jianshu.com/p/2cb959529c96