众所周知,http协议是一种未加密的协议,我们未加密的数据,在传输的过程中会经过一个又一个的物理节点,如果被人通过抓包的方式拿到了我们的数据,将会给我们造成无法估量的损失。
为了解决解决这个问题,https应运而生。https通过加密的手段,保障的数据的安全性。那https的怎么加密的呢?这就是我们接下来需要讨论的内容。
什么是对称加密?
简单说就是有一个密钥,它可以加密一段信息,也可以对加密后的信息进行解密,和我们日常生活中用的钥匙作用差不多。
比如说小明需要给小红发送一条:Hello World,为了保证数据安全,小明把所有字母往后移动了一位,发送时的消息就变成了:Ifmmp Xpsm。
小红收到消息后,再把字母顺序往前移动一位,就得到了Hello World。
这样,即使攻击人拿到密文,他不知道怎么解密的密钥,也无法得到密文内容。

使用对称加密,即使数据被截获,但是他没有密钥,他无法得到密文内容,也无法修改。
但是对称加密有一个问题,如何让双方都用同一个密钥进行数据加密,同时不被别人知道
如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器只要预存好世界上所有HTTPS网站的密钥就行了!这么做显然不现实。
什么是非对称加密?
简单说就是有两把密钥,通常一把叫做公钥、一把叫私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。
如何使用非对称加密呢?
假如,客户端需要向服务器发送一条数据,浏览器需要保障数据的安全性,加密流程如下:

非对称加密能让双方进行数据交换,但性能不行,对称加密性能不错,但是无法确认双方的加密密钥,那用非对称加密完成对称加密的密钥交换,之后再用对称加密进行加密不就可以了吗?
流程如下:
完美!这样非对称加密的性能问题也解决了。
但是,这里面还是有漏洞。

如果在数据传输过程中,中间人劫持到了数据,此时他的确无法得到浏览器生成的密钥X,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开它,然而中间人却完全不需要拿到私钥A’就能干坏事了。请看:
通过这一通操作,攻击者就知道服务器和浏览器之间的公钥了,这样,对称加密就形同虚设了。
为什么会发生这样的事?因为浏览器拿到公钥的时候,他无法确定这个公钥是服务器的。在传输过程中,公钥被篡改,一方用篡改后的公钥加密,非对称加密形同虚设。
如何证明浏览器收到的公钥一定是该网站的公钥?这个时候,就要引入第三方机构了,也被称作CA机构。
CA机构怎么解决浏览器无法确认收到的公钥是不是网站自己的问题呢?
网站只需要向CA机构申领一份数字证书,这份证书里面,包括了网站的公钥,网站的域名和其他一些网站基本信息。
然后CA机构用自己的私钥对证书进行加密,同时生成一段密文,这段密码就叫做数字签名
数字证书的生成过程如下:

证书的内容大概长这样

之后的浏览器验证流程如下:
** 为什么S和T不一样,说明证书就被篡改了呢?**
这里是理解证书认证的关键,仔细思考,数字签名是用CA机构的私钥加密的,CA机构的私钥只有CA机构自己知道,如果证书被中间人劫持,他拿到证书,修改了证书中的公钥,因为公钥修改后,数据的Hash值,就和数字签名解密后的Hash值不同了,浏览器就知道证书被动过,而中间人无法伪造数字签名,因为数字签名是用CA机构的私钥加密的,他要伪造,就必须拿到CA机构的私钥!
中间人有可能把证书掉包吗
假设有另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?
其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。
浏览器怎么得到CA机构的公钥
CA机构的公钥去通过网络获取,如果通过网络去获取,那CA机构生成的证书就没意义了。
一般浏览器会内置主流的CA机构的公钥。
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or