http协议原理
1. 利用DNS协议进行域名解析
2. 建立tcp协议三次握手过程
3. 客户端发出访问网站相应页面请求(发出http协议请求报文)
4. 系统架构部署情况
5. 服务端发出响应访问页面的请求信息(发出http协议响应报文)
6. 断开tcp协议四次挥手过程
三次握手以后。。开始了数据传输过程。。如果是https进行加密传输。。。
ex:
https://www.jianshu.com/p/2b89b7ac7c9dhttps://blog.csdn.net/baidu_37964071/article/details/80500825?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
查询ip
查询缓存(如果有返回ip)--查询本地域名服务器(如果有返回ip)
查询域名服务器
本地域名服务器—---根域名服务器(返回要查询的顶级域名服务器地址)-—查询返回的顶级域名服务器(返回权限域名服务器)
查询ip
本地域名服务器—--权限域名服务器(也就是网站注册时候的关联域名服务器直接根据映射表返回ip)
1. 利用DNS协议进行域名解析
域名:www.baidu.com 对应ip 级别从左往右逐渐增高。。。
域名服务主要是基于UDP实现的,服务器的端口号为53。
从大到小: 根域名服务器、顶级域名服务器、权限域名服务器、本地域名服务器
第一步:浏览器里输入www.baidu.com网站地址,回车
查找系统本地浏览器、本机、路由器统称本地DNS缓存,查找是否存在www.baidu.com域名对应的IP解析记录,如果有就直接获取IP地址冰访问IP地址对应域名www.baidu.com的服务器(一般第一次请求某地址是没有解析记录的)
第二步:如果没有则转给本地域名服务器LDNS解析,有则返回。没有则跳转root server进行解析
第三步:根域名会根据所查询域。返回给ldns一个主域名服务器(如.com.cn.org)地址;
第四步:此时ldns发送请求给这个主域名服务器。主域名则返回对应的NameServer。(nameServer就是网站注册时候关联的域名服务器),nameServer根据映射表找到ip给ldns
第五步:LDNS把收到的来自授权DNS服务器www.baidu.com对应的IP解析记录(A记录)缓存到本地,再发给客户端,以便下一次更快的返回相同解析请求的记录,这些缓存记录在指定的时间(DNS TTL值控制)内不会过期。
第六步:客户端浏览器获取到了www.etiantian.org的对应IP地址的解析记录,会先缓存到本地,接下来,浏览器会请求获得的IP地址对应的网站服务器
2. 建立tcp协议三次握手过程
UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP。对应的应用层的协议主要有 DNS,TFTP,DHCP,SNMP,NFS 等。
TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,TELNET,HTTP,FTP 等。
TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。
三次握手:
最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。
1、TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。(客户端发送消息。告知服务器。我要发送报文了,一次握手)
2、TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。(服务器发送消息告知客户端,可以发送了。二次握手)
3、TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。(像服务器发送确认发送请求,开始发送数据。三次握手)
当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
3. 客户端发出访问网站相应页面请求(发出http协议请求报文)
4. 系统架构部署情况
5. 服务端发出响应访问页面的请求信息(发出http协议响应报文)
6. 断开tcp协议四次挥手过程
1、客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。(客户端告诉服务器,我要停止发送,一次挥手)
2、服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。(服务器给客户端发送确认报文,但服务器还可以继续发送,二次挥手)
3、客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。(服务器给客户端发送完最后数据,再次发送确认,三次挥手)
4、客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗
∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。(客户端发送给服务器确认关闭,四次挥手,双方关闭)
为什么客户端最后还要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
通过抓包可以看到数据不是明文传输,而且HTTPS有如下特点:
窃取、篡改、冒充。。。
内容加密:采用混合加密技术,中间者无法直接查看明文内容
验证身份:通过证书认证客户端访问的是自己的服务器
保护数据完整性:防止传输的内容被中间人冒充或者篡改
http://www.360doc.com/content/14/0808/14/17799864_400329626.shtml
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
https://www.jianshu.com/p/b894a7e1c779?utm_campaign=hugo&utm_medium=reader_share&utm_content=note
传输给对方,过程中容易被看到怎么办?
HTTP 面临的第一个问题,这个问题通常被叫做 “窃听” 或者 “嗅探” ,这种问题通常是通过“加密”来解决的。一般是采用一种叫做 AES 的算法来解决的。这种算法需要一个 密钥 key 来加密整个信息,加密和解密所需要使用的 key 是一样的,所以这种加密一般也被称为“对称加密”。AES 在数学上保证了,只要你使用的 key 足够足够足够足够的长,破解是几乎不可能的。
问题来了。key 怎么给目的地啊?
非对称加密。生成一对密钥 (k1, k2)。凡是 k1 加密的数据,需要 k2 才能解密;凡是 k2 加密的数据,k2 不能解密,需要 k1 才能解密。这种算法事实上有很多,常用的是 RSA,其基于的数学原理是两个大素数的乘积很容易算,而拿到这个乘积去算出是哪两个素数相乘就很复杂了。好在以目前的技术,分解大数的素因数确实比较困难,尤其是当这个大数足够大的时候(通常使用2的10次方个二进制位这么大),就算是超级计算机解密也需要非常长的时间。
你把 k1 用明文发送了出去,路经有人或许会截取,但是没有用,k1 加密的数据需要用 k2 才能解密。而此时,k2 在你自己的手里。k1 送达目的地后,目的地的人会去准备一个接下来用于对称加密传输的密钥 key,然后用收到的 k1 把 key 加密了,把加密好的数据传回来。路上的人就算截取到了,也解密不出 key。等到了你自己手上,你用手上的 k2 把用 k1 加密的 key 解出来,现在全教室就只有你和你的目的地拥有 key,你们就可以用 AES 算法进行对称加密的传输啦!这时候你和目的地的通讯将无法再被任何人窃听!
当然,这时候你可能会问两个问题。
既然 非对称加密 可以那么安全,为什么我们不直接用它来加密信息,而是去加密 对称加密 的密钥呢?
这是因为 非对称加密 的密码对生成和加密的消耗时间比较长,为了节省双方的计算时间,通常只用它来交换密钥,而非直接用来传输数据。
使用 非对称加密 是完全安全的吗?
传说中的“中间人攻击”。我们将你称为 A,你的目的地称为 B,而中间人称为 M。当你要和 B 完成第一次密钥交换的时候,途径了 M。M 知道你要进行密钥交换了,它把小纸条扣了下来,假装自己是 B,伪造了一个 key ,然后用你发来的 k1 加密了 key 发还给你,你以为你和 B 完成了密钥交换,实际上你是和 M 完成了密钥交换。同时 M 和 B 完成一次密钥交换,让 B 误以为和你完成了密钥交换。现在,由 A -> B完整的加密,变成了 A(加密连接1) -> M(明文)->B(加密连接2)的情况了。这时候 M 依然可以知道 A 和 B 传输中的全部信息。
对于这种事,我们似乎很难找到一个解决方法来解决这个问题,除非我们能从源头保证,你密钥交换的对象是安全的。这时候我们就要认识互联网 HTTPS 和你传纸条的微妙区别了。你传纸条时,你和你的目的地的关系几乎是对等的。而你访问网站时,你访问的对象通常是一个比较大的服务供应商,他们有充沛的资源,也许可以证明他们的合法性。
这时候我们会引入一个第三方叫做 CA。CA 是一些非常权威的专门用于认证一个网站合法性的组织。服务商可以向他们申请一个证书,使得他们建立安全连接时可以带上 CA 的签名。而 CA 的安全性由操作系统或浏览器来认证。你的 Windows、Mac、Linux、Chrome、Safari 等会在安装时带上一个他们认为安全的 CA 证书列表。如果和你建立安全连接的人带着这些人的签名,那么认为这个安全连接是安全的,没有遭到中间人攻击。
CA 证书通常情况下是安全的。因为一旦某个 CA 颁发出的某个证书被用于了非法用途,浏览器和操作系统一般会通过更新将整个 CA 颁发过的全部证书全部视为不安全。这使得 CA 通常在颁发证书时是比较小心的。
所以通过 对称加密 + 非对称加密 + CA认证 这三个技术混合在一起,才使得 HTTP 的后面加上了一个 S —— Security。实际上 HTTPS 的协议比我这里描述的更复杂一些,我这里说的主要是基本的实现原理。因为其中任何一环稍有闪失,就会使得整个加密都将变得不安全。这也是为什么 HTTPS 的加密协议从SSL 1.0 升级到 SSL 3.0 再被 TLS 1.0 现在被 TLS 1.2 取代,其背后都是一环环细节上的修改,以防任何地方的闪失。
但即使如此,你的 HTTPS 尽可能的保证了你传输的安全,但这种安全也不是绝对的。比如 CA 证书出了问题被用于了中间人攻击,在短期内,你的安全将会陷入直接的麻烦直到浏览器或操作系统重新更新了你的 CA 列表或者你手动调整了这个列表。但大多情况下不必杞人忧天,它基本上是安全的。
当然了,路由也可以选择直接丢包,它看不到的,也不让你看到。
网际层协议:IP协议、ICMP协议、ARP协议、RARP协议。
传输层协议:TCP协议、UDP协议。
应用层协议:FTP、Telnet、SMTP、HTTP、RIP、NFS、DNS。【BGP和RIP是应用层协议.尽管他们是路由协议,用来影响网络层的,但他们真的是工作在应用层的啊.】
判断:
http协议属于网络层协议。(X)
加密方式:
对称加密:AES/DES;非对称加密:RSA;哈希算法:md5,SHA1,SHA256;base64编码
对称加密
加密/解密使用同一密钥、过程可逆
DES 数据加密标准
AES 高级加密标准
AES算法因密钥建立时间短、灵敏性好、内存要求低等优点,AES算法成为DES算法的替代者。
提示:
加密过程是先加密,再base64编码
解密过程是先base64解码,再解密
适用业务场景:1.网络请求过程中的敏感信息,请求的时候用AES加密请求数据,服务端返回的时候客户端去解密;2.如果有数据库的时候,数据库里面的数据也可以加密好给到客户端,防止被人破解.
下面请看一段AES加密,解密代码
+ (NSString *)obourkey{
NSString *key = [@"你的key" stringByReplacingOccurrencesOfString:@"要替换的字符串" withString:@"替换后的字符串"];
return key;}
//加密
+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
return base64EncodedString;
}
//解密
+ (NSString *)decrypt:(NSString *)base64EncodedString{ NSData *encryptedData = [NSData base64DataFromString:base64EncodedString]; NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:[[[AESCrypt obourkey] dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil]; return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];}
非对称加密RSA
非对称加密的特点
使用 公钥 加密,使用 私钥 解密
使用 私钥 加密,使用 公钥 解密(私钥签名,公钥验签)
公钥是公开的,私钥保密
加密处理安全,但是性能极差
经典算法-->RSA
使用场景:
1.比如支付宝开放平台的支付业务,支付宝会让你生成公私钥(openssl可以直接生成),私钥放在自己的服务端(切记),公钥上传到支付宝的商户平台,拿到订单信息的时候,请求服务端通过私钥签名后的订单信息,然后调用支付宝的sdk,支付宝会拿公钥来验签,验证成功之后才会进入支付选项。
2.Https网络请求的SSL层SSL层的简单过程如下
首先了解:
混合加密手段:针对非对称加密算法的效率低问题,各密码学机构主张将对称加密算法与非对称加密算法相结合,使用对称加密算法为数据加密/解密,使用非对称加密算法的公钥和私钥为对称加密算法的密钥加密/解密。利用对称加密算法的高效性,加之非对称加密算法的密钥管理,提升整体加密系统的安全性。SSL加密通道上的数据加解密使用对称密钥算法。眼下主要支持的算法有DES、3DES、AES等,这些算法都能够有效地防止交互数据被窃听。与非对称密钥算法相比。对称密钥算法具有计算速度快的长处,通经常使用于对大量信息进行加密(如对全部报文加密);而非对称密钥算法,一般用于数字签名和对较少的信息进行加密。
数字签名:非对称密钥算法能够用来实现数字签名。因为通过私钥加密后的数据仅仅能利用相应的公钥进行解密,因此依据解密是否成功,就能够推断发送者的身份。如同发送者对数据进行了“签名”。比如。Alice使用自己的私钥对一段固定的信息加密后发给Bob,Bob利用Alice的公钥解密,假设解密结果与固定信息同样。那么就能够确认信息的发送者为Alice,这个过程就称为数字签名。
数据的完整性:MAC算法是在密钥參与下的数据摘要算法,能将密钥和随意长度的数据转换为固定长度的数据。利用MAC算法验证消息完整性的过程如图2所看到的。发送者在密钥的參与下,利用MAC算法计算出消息的MAC值。并将其加在消息之后发送给接收者。接收者利用相同的密钥和MAC算法计算出消息的MAC值。并与接收到的MAC值比較。假设二者相同。则报文没有改
下面对流程图用文字的形式解释一遍:
1)客户端发起一个https的请求,把自身支持的一系列Cipher Suite(密钥算法套件,简称Cipher)发送给服务端
2)服务端接收到客户端所有的Cipher后与自身支持的对比,如果不支持则连接断开,反之则会从中选出一种加密算法和HASH算法,以证书的形式返回给客户端。
3)客户端收到服务端响应的证书后
第一步、校验证书的是否有效。
第二步、生成随机密码。如果证书验证通过,或者用户接受了不授信的证书,此时浏览器会生成一串随机密码,然后用证书中的公钥加密。
第三步、用最开始约定好的HASH方式,把握手消息取HASH值,把用 `随机数密码`加密 “握手消息+握手消息HASH值(签名)”和用公钥加密的随机密码 一起发送给服务端。
把握手消息做一个签名,用于验证握手消息在传输过程中没有被篡改过。
4)服务端拿到客户端传来的密文,用自己的私钥来解密,获取随机密码,再用随机数密码 解密 握手消息与HASH值,并与传过来的HASH值做对比确认是否一致。然后用随机密码加密一段握手消息(握手消息+握手消息的HASH值 )给客户端。(此时服务器端已经获取到了客户端生成的随机密码了)
5)客户端用随机密码解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束。
之后所有的通信数据将由之前浏览器生成的随机密码作为对称加密算法的密钥对数据进行加密或解密。
哈希算法:md5,SHA1,SHA256;一般业务场景,云端的视频可以通过算法生成md5来判断资源文件是否一致。
编码方案:Base64,一般我们不想让别人直接看到的信息,可以用Base64简单处理,比如某些网站的单词查询,就是讲单词的base64字符串拼到最后。base64实际来说并不是一种加密方式,是一种隐藏明文的编码方式。
基于、加密实现上,https等其实还有很多内容。包括三次握手、四次握手、防止公钥篡改而应用证书机构等问题。详情可以参考文献:https://www.wosign.com/news/httpsjiami_20180817.htm还是写的很不错的。