摘要
招聘者大大,您知道什么是要求播放吗?我曾在面试中遇到过中间人攻击这个问题,当时我还不知道这是啥,只能瞎猜。结果,我就凉了。要避免这种攻击,就要了解它的本质。虽然学术上的定义有点枯燥,但我们必须要认真对待。
正文
招聘者:啥是要求播放呀?
它是why的第 103 篇原創
你好啊,我是why。
如图所示,中间人攻击,这题我确实在招聘面试的情况下遇到过,2次。
印像较为深的是第一次碰到这一面试问题的情况下,也是第一次听见“中间人攻击”这个词的情况下,一脸迷惑,因此我也连蒙带猜的,向着插口幂等性的方位去答了。
結果就凉了。
要回应如何避免中间人攻击,那麼大家得了解啥是中间人攻击。
学术研究上的表述是那样的:
中间人攻击(英文:replay attack,或称之为回看进攻)是一种故意或诈骗的反复或延迟时间合理数据信息的黑客攻击方式。 这能够由发动者或由阻拦数据信息并再次传送数据的敌人来实行,这可能是根据IP数据文件更换开展的蒙骗进攻的一部分。 它是“重放攻击”的一个较低等级版本号。
这类进攻的另一种叙述是: “从不一样前后文将信息回播到安全协议书的预估(或初始和预估)前后文,进而蒙骗别的参加者,导致她们误认为早已取得成功完成了协议书运作。”
举个简易的事例:
大家程序猿日夜劳碌的,在按摩会所里边办个卡,有时候去洗个脚放松一下但是分吧。
有一天,我要去泡脚的情况下冲着营业员说:帮我分配一个 168 价格的,要小伙儿啊,按照较为带劲儿,我的信用卡卡号是 88888888。
随后我还在前台接待签到了自身的名称,营业员就分配了一个健壮的小伙儿帮我推拿。
想不到大家的会话被别人听到了,因此他也给营业员说:帮我分配一个 168 价格的,要小伙儿啊,按照较为带劲儿,我的信用卡卡号是 88888888。
还效仿了我的签字,在前台接待签名。
把以前的、一切正常的要求再度推送,这就是中间人攻击。
有的盆友便会讲了:我的插口是加签的,应当没什么问题吧?
你加签怎么了?
也没有动你的报文格式,因此 你也能够一切正常验签呀。
我不但抄你报文格式里边的一切正常字段名,报文格式里边的签字因为我抄全乎了。
因此 ,接受方收到报文格式以后能一切正常验签。
沒有一切问题。
有的盆友还会继续讲了:我的插口是有数据加密的,应当没什么问题吧?
来看还是不懂中间人攻击的基本概念。
你数据加密怎么了?
总之我提取到你的报文格式,尽管你报文格式数据加密了,我看上去是一段错码,可是我也不必须了解你报文格式的主要内容呀,立即再发就完了了。
或是前边的事例。
假定我要去泡脚的情况下冲着营业员说:天王盖地虎。
被边上的人听到了,他压根就不清楚“天王盖地虎”是什么。
可是他看到了我说了他们以后,就被分配了一个 168 元的技术咨询。
因此他也对营业员说:天王盖地虎。
也可以被分配。
因此 ,他人压根就不用了解你报文格式的实际含意。
只需我再度发给你,你开展破译实际操作,发觉能破译。
能破译表明暗语对到了。
因此 ,尽管报文格式是数据加密、加签传送的,针对避免要求播放,并没什么用处。
数据加密加签
来,说解决方法以前,大家先确立2个定义:数据加密和加签。
字面意思无需多言了,大家都了解,说说目地。
数据加密的目地:为了更好地确保传送信息内容的个人隐私性,不被他人见到传送的主要内容,只有让接受方见到恰当的信息内容。
加签的目地:信息接受方认证信息内容是不是合理合法的推送方推送的,确定信息内容是不是被别人伪造过。
无论是数据加密或是加签,都牵涉到公与私钥。
记住了:公匙数据加密、公钥加签。
简易的说一下基本原理。
推送方有那样三样物品:自身的公钥、自身的公匙、接受方的公匙。
接受方有那样三样物品:自身的公钥、自身的公匙、推送方的公匙。
中介人有那样两种物品:接受方的公匙、推送方的公匙。
为什么是公匙数据加密呢?
再来一个反证法嘛。
假定信息推送方用自身的公钥数据加密。随后信息被中介人阻拦到,由于他有推送方的公匙,那麼中介人就可以用公匙对信息开展破译,获得密文报文格式,那样达不上数据加密的目地。
因此 ,恰当的实际操作应该是用接受方的公匙数据加密,那样即使信息被中介人阻拦到,他都没有接受方的公钥呀,解不上密,看不见密文。
为什么是公钥加签呢?
一样,反证法。
假定信息推送方,用接受方的公匙加签。假如信息被中介人阻拦到,巧了,因为我有接受方的公匙。咔一下,立即把信息一改,随后也拿着接受方的公匙加签,发过去。
那样的加签是没有意义的。
因而,要用自身的公钥加签,即使被阻拦,中介人沒有公钥,改动报文格式以后,搞不上签字,也就没啥用处。
前边讲了,针对中间人攻击,提取到的內容是否数据加密都不在乎。由于我压根不用大家在说些什么,我只必须把阻拦出来的要求一遍遍的再发就可以了。
因此 ,关键的是加签和验签。
假如你能改动报文格式,而且再次加签,那么就不叫中间人攻击了,那么就称为重放攻击了。
实际上中间人攻击也是“重放攻击”的一个较低等级版本号。
啥是重放攻击呢?
我要去泡脚的情况下冲着营业员说:帮我分配一个 168 价格的,要小伙儿啊,按照较为带劲儿,我的信用卡卡号是 88888888。
会话被窃听到,中介人对营业员说:帮我分配一个 1999 价格的,要小姑子凉啊,按摩方法好一点的,我的信用卡卡号是 88888888。
伪造报文格式,它是重放攻击。
文中关键聚焦点于中间人攻击的解决方法。
历经前边的剖析,我们知道要处理中间人攻击,便是惦记着怎样在参加签字的字段名里边搞事。
能想起这儿,就比较好回应这个问题了。
假如是以数据库加密视角回应这个问题的同学们,能够回来等通知了。
此外,说到数据加密了,大伙儿都是会想起 HTTPS 数据库加密。
因此 ,当招聘者询问你:HTTPS数据库加密是不是能够避免中间人攻击?
答:否,数据加密能够合理避免密文数据信息被监视,可是却避免不上中间人攻击。
下面,大家看一下解决方法。
解决方法
加时间格式
最先,普遍的解决方法便是在要求报文格式里边再加上时间格式,并参加加签。
当接受方接到报文格式,历经验签以后。
最先第一个事情便是拿着要求中的时间格式字段名和当地時间做一个比照。
假如时间误差在特定時间,例如 60 秒内,那麼觉得这一要求是有效的,程序流程能够再次解决。
为何要有一个時间容错机制范畴,能了解吧?
由于报文格式的传送、破译、验签是必须時间,不可以假定我这一秒传出去,下一秒服务器端就收到了。
因此 ,得有时间容错机制范畴。
可是这一容错机制范畴又产生了此外一个难题。
不可以避免中间人攻击。
最少時间容错机制范畴内,例如 60 秒,重发来的要求,服务器端觉得是合理的。
那麼怎么办呢?
加任意串
换一个构思,我们在要求报文格式里边加个任意串,随后让它参加加签。
接受方接到报文格式,验签以后,把任意串拿出来,来分辨一下这一任意串是不是早已解决过去了。例如分辨一下是不是存有于 Redis 里边。
当要求再度重放过来的情况下,一看:嚯,好家伙,这一任意串早已被使用过了呀,不解决了。
在这个状况下,任意串就得确保唯一性了,还得历史时间全局性唯一。
由于你指不定哪一天就接到一个几日前的被重放过来的要求。
的确是解决了要求播放的难题,可是缺点也很显著:历史时间全局性唯一。
我都得储存出来,并且储存的信息量还会继续越来越大,是否有点儿麻烦了?
的确麻烦了。
这一观念就和用全局性唯一单号去确保插口幂等性很像了。
因此 ,我第一次碰到这一面试问题的情况下,我向着插口幂等的视角去回应了,也不能说回应的不对。
只有说回应的并不是招聘者要想的正确答案。
那麼什么叫招聘者要想听见的回应呢?
时间格式 任意串
时间格式的难题是有一定的時间容错机制对话框,这一周期时间内的中间人攻击是防不了的。
任意串的难题是要确保历史时间全局性唯一,储存任意连接成了一个不便的事儿。
那麼在我们把这两个计划方案揉在一起的情况下,奇妙的事儿就发生了:
我只必须确保周期时间内的转化成的任意串不反复就可以了。
并且假定周期时间为 60 秒,大家用 Redis 来纪录发生过的任意串,那麼这一串在后台管理的请求超时时间设置为 60 秒就可以了。
一般来说这一周期时间都不容易太长了,我对接到这么多各式各样的方式,见过最多的也就 5 分鐘。
确保 5 分鐘内转化成的2个任意串不反复,这一要求比确保完成一个历史时间全局性唯一的单号非常容易完成多了吧?
此外,最重要的一句话一定说起:时间格式和任意串得参加到加签逻辑性中去。
这一非常好了解吧?
接受方看报文格式是不是被伪造,看的便是签字是不是能配对上。
而签字的結果是和参加签字的字段名的值有立即关联的。
如果你时间格式和任意串不参加加签,那麼随意改动时间格式或是任意串,都不容易造成签字的转变,那变白累成狗一场吗?
中介人咔一下阻拦到要求,发觉有时间格式和任意串,正提前准备舍弃的情况下,惦记着死马作为活马医,把任意串一改,又丢给接受方了。
結果接到恰当的回应了。
我如果这一中介人,我都是会笑出去声来:写这一编码的程序猿也太讨人喜欢了吧?
微信付款
实际上说到时间格式加任意串的情况下,我也想到了微信付款。
刚入门的情况下,但是被这一微信付款搞的服服贴贴的。
可是必须表明的是,尽管它的api文档里边也是有时间格式加任意串,可是目地并不是为了更好地避免中间人攻击的。
写出去呢仅仅为了更好地让针对加签这个东西不太熟的盆友有一个实际的认知能力。
来,大家看一下微信付款的api文档:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
能够见到要求主要参数里边的确有时间格式(timeStamp)和随机字符串(nonceStr),且别人还专业字体加粗了:
参加签字的主要参数为:appId、timeStamp、nonceStr、package、signType,主要参数区别英文大小写。
那麼是怎么签名的呢?
官方网也是给了详细的表明的:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
最先便是依照字典序,对全部必须参加签字的、非空的字段名开展排列。并应用 URL 键值对的文件格式(即key1=value1&key2=value2…)拼凑成字符串数组 stringA。
随后在 stringA 最终拼凑上 key(商家密匙) 获得 stringSignTemp 字符串数组,并对 stringSignTemp 开展 MD5 计算,再将获得的字符串数组全部字符转换为英文大写,获得 sign 值 signValue。
官方网给了一个具体的实例,以下:
再说一次:微信付款的插口里边尽管有时间格式加任意串,可是目地并不是为了更好地避免中间人攻击的。写在这儿仅仅让大伙儿针对加签这一全过程有一个实际的认知能力。
别整茬了。
那麼它在插口里边添加任意串的目地是什么呢?
官方网自身都说了:
微信付款API通讯协议中包括字段名nonce_str,关键确保签字不能预测分析。大家强烈推荐转化成随机数算法以下:启用随机数函数转化成,将获得的值变换为字符串数组。
阿里巴巴API网关ip
看了微信付款,再看一下阿里巴巴的 API 网关ip是怎么避免中间人攻击的。
https://help.aliyun.com/knowledge_detail/50041.html
阿里巴巴的 API 网关ip,便是在 HEADER 里边加了2个主要参数:X-Ca-Timestamp、X-Ca-Nonce。
这一解决方法便是大家前边说的时间格式加任意串。
然后看一下它的签名生成全过程。
最先是手机客户端转化成签字,三步:
1.从初始要求中获取重要数据信息,获得一个用于签字的字符串数组 2.应用加密技术加APP Secret对重要数据信息签字串开展数据加密解决,获得签字 3.将签字所有关的全部头添加到初始HTTP要求中,获得最后HTTP要求
一图胜万言:
随后是服务器端认证签字,四步:
1.从接受到的要求中获取重要数据信息,获得一个用于签字的字符串数组 2.从接受到的要求中载入APP Key,根据APP Key查看到相匹配的APP Secret 3.应用加密技术和APP Secret对重要数据信息签字串开展数据加密解决,获得签字 4.从接受到的要求中载入手机客户端签字,比照服务端签字和手机客户端签字的一致性。
而实际的签字优化算法实际上和微信付款,如出一辙,关键也是针对参加签字的字段名依照字典序排列。
其中差别也不开展比照表明了,有兴趣爱好的盆友能够自身看一下。
最终说一句
好啦,看到了这儿点个赞吧,周更非常累的,必须一点反馈调节。
孤陋寡闻,在所难免有疏漏,假如你发觉了不正确的地区,能够在留言板留言区明确提出来,我对其多方面改动。
感谢你们的阅读文章,我坚持不懈原創,十分热烈欢迎并感谢你们的关心。
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0