HI,下午好,欢迎来到新媒体服务!
24小时服务热线: 4000-163-301

新闻动态

NEWS CENTER

,数据库采用加密的方式保存密码,而且一定是单项的,只能加密,不能解密

2020-04-10

假设,用户名为tom,密码为123456。则用户登陆时,把tom和123456 POST到服务器。服务器去数据库里一找,发现有tom,密码也确实是123456,那么就登陆成功,也就是完成了身份认证。

这是典型的明文账户系统。它最大的缺点,是不安全。一旦数据库泄露,就知道了用户的密码,这个时候,就可以去撞库(用tom的密码123456去登陆tom在别的的账号)。

有时候,明文保存密码是黑客特意设置的,黑客设置一个吸引别人用邮箱去注册,明文保存了用户的密码。

为了安全起见,数据库采用加密的方式保存密码,而且一定是单项的,只能加密,不能解密。


如上图所示,这是经过md5处理的密码。当用户登陆的时候,发送用户名和经过md5处理的密码,后台去数据库里查询,查询到了说明登陆成功,否则就是登陆失败。

这样的好处是,黑客嗅探出了你的密码,也仅仅能登陆你登陆的这个,他不能还原出你加密前的明文,也就无法去撞库。即便数据库泄露了,也很难知道你真正的密码。

但是,现在有一些md5搜集器,搜集了很多明文密码,并使用md5加密后存在数据库里。


这样,如果你的密码是常规的密码,则很容易被逆向(查询)出来。比如:


它很容易就能查出你的原始密码,它仅仅是查询,而不是破解。因为有大量的常规的普遍的密码和加密后的md5被存进去。

如果想进一步安全,怎么办?办法也是有的,那就是使用公私钥的方式。


用户登陆,系统产生一个随机数,发送给用户。用户需要使用私钥对这个随机数进行签名,发给系统。系统用公钥验签,完成身份认证。

虽然这种方法安全,但是认证时间长,对服务器造成的压力也很大。在做产品设计的时候,成本因素也是一个必须考虑的问题,包括时间成本,服务器算力成本等。

这需要产品经理根据应用场景及安全级别去评估,取舍。而不是一味的选择更安全的系统。

刚才提到的是用户身份验证。而API中,更多的操作,是针对某个产品的权限的。


如上图所示,一个用户可以创建多个项目,每个项目都有一个key。我们假设,应用1用的是简单身份验证,应用1的key是一个具备一定长度的字符串。任何人只要知道这个字符串,就可以对其进行操作。

应用2比应用1安全一些,采用的是keyID+keySecret的方式,也就是hmac-sha256签名机制。它会用密钥对keyID、调用的API、参数、时间等进行签名,因为服务器也有一个相同的keySecret,可以用来验证签名,以确定身份。

应用3就是更安全的,它有keyID和keyPubkey,即公钥。调用的时候,使用私钥对API、方法、参数、时间等进行签名,服务器使用私钥对应的公钥对签名进行验签,但时间会长一些。


总结一下, 通常API身份验证有两种:简单身份验证,和签名身份验证。下面举例子,说明哪些领域使用哪些身份验证方法。

通常情况而言,使用javascript调用的API,基本上使用的是简单身份验证,而且用的是url传key的方式。比如,百度地图的key,在调用的时候,是直接构建在url里的:

 type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥">

这意味着,你的key很容易泄露。比如,稍微懂前端的,就可以从源码里看到你的key。以及,懂点网络嗅探的,也能轻而易举能得到key。因此对于简单身份验证,还需要一个ip或域名白名单进行配合。这样,即便别人获得了你的key,也无法使用你的key,除非他同时入侵了你的服务器,在你的ip上面进行操作。

post传key和header传key没有本质上的区别。例如,remove.bg 的API,使用的是headers传递key,它也是简单身份验证,没有进行签名。

$ curl -H 'X-API-Key: YOUR_API_KEY'                     \
       -F 'image_file=@/path/to/file.jpg'                \
       -f https://api.remove.bg/v1.0/removebg -o no-bg.png

而微信的API,则需要签名。如微信支付的签名算法:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:

相关推荐