@
MinonHeart 要单向的传输(只返回密码是否正确,不返回密码的明文或者密钥),我给你举个例子
a服务器(作为发起请求的一端)
b服务器(账号密码所在服务器,接受查询账号密码是否正确)
用户名abc
密码123
方法1
a网站没有存储账号密码,也不知道服务器上真实的用户密码是什么,每次查询的时候向服务器发送账号密码,或者不发送密码,只发送签名
a服务器接受用户输入的数据,比如说abc,123,那么如何知道正确与否?一般情况下是对比数据库里的值,这里账号密码数据库不在a服务器上,无法直接对比(对比就要取出数值)。
现在a服务器要验证账号密码是否正确就要向b服务器发起请求(在后端发起请求,避免被客户端劫持数据),比如说请求http://xxx.xx/login?user=abc&password=123,服务器返回数字1为验证通过,返回0为验证失败。
在这样的情况下,a服务器即便被盗,被拿到root权限,拿到数据库,也不知道密码是什么(当然a服务器偷偷记录下用户的密码那就是另外一回事了)
这里你可能要说了,密码不是被发送到服务器了吗,还是明文的,这样安全吗?(一般不会用http传输,会用https传输,防止服务器端被机房其他机器或者网关劫持)
总结:服务器后端传输密码,需注意服务器端所在网络是否劫持,当然了https一般情况是无法劫持的
方法2
a服务器不向b服务器发送密码,只发送签名,这样双方都不知道对方所知道的账号和密码
何为签名?那就是a服务器用abc和123进行hash处理(一般为了防止每次hash都一样,会带上时间戳,并限制时间在当前时间的一定范围之内,比如一般会要求双方服务器时间差距不能超过60秒或者30秒)。比如说md5,或者sha1。下面我以md5为例子(算法md5(abc+123))。
http://xxx.xx/login?user=abc&time=xxxxxxx&hash=A6091522F955F170
b服务器获取abc,然后查询数据库里的abc的密码,进行同样的hash计算(我md5没带上时间戳,正常情况是要带上时间戳一起运算,服务器需要对时间进行判断,不能超过当前时间的一定范围),最后对比a服务器发来的hash是否一致,一致的话。返回1代表正确,返回2代表错误
总结:双方服务器都不知道对方所知的密码是什么,传输也不带密码,安全性很高!
方法3
a服务器不知道用户在b服务器输入了什么账号什么密码
a服务器需要验证用户账号的地方跳转到B服务器,并带上一个随机生成的字符串,比如sdfht32sh38作为会话id的依据(比如跳转到b服务器的网址http://xxx.xx/login?id=sdfht32sh38),然后用户在b网站进行登录操作,b服务器验证用户密码是否正确,正确则在用户浏览器跳转回a服务器,并且在后端请求a服务器,把结果发送过去,以及本次的id就是sdfht32sh38,并且提供用户特征(为防止a服务器得知用户的用户名后跑到b服务器去破解,所以只给特征,比如说cba,如果在必须知道用户名的情况下,返回用户名,并且返回一个签名,确保本次通讯的可靠性,一般是a服务器有一个证明自身的用户名和密码,双方才可以此确保请求是否是对方发来的,并非虚假的请求,所以一般服务器通讯的时候也会带上这个用户名)
总结:a服务器不知道用户在b服务器输入了什么账号什么密码,只知道登录用户的特征,只知道对方登录是通过验证的。如果用户输入的账号和密码错误,a服务器得不到任何东西。
方法3也是各大网站登录api的原理,算法可能更加高级,但是过程大概就是这样,包括银行网上交易,网上付款也是同样的过程!所以安全性可以说非常高。
当然啦,也不是没有破解的方法啊,比如a服务器模拟b服务器的页面给用户,用户以为自己是在b服务器,实际上是在a服务器……
所谓拖库,一般是能连上账号密码所在服务器,然后导出用户信息,一般来说,现在都会对用户密码进行hash处理并且加入随机字符串。所以黑客能得到的只是一个加密后的字符串,无法进行破解,当然了,如果黑客还拿到了这个密文的运算方式(比如知道我是md5(abc+123)这样计算,就可以自己写算法来进行破解,拖库不一定知道算法,但是算法和密文都知道的话……那破解只是时间问题了,除非密码非常复杂,或者算法非常耗时,才能防止被破解)
再当然了,因为网页的话都是服务器先发送登录页面代码给用户,如果在这做手脚的话,什么算法什么安全方式都扯淡。