安全地将Oauth令牌存储在文件中
我正在用Python开发一个小的网页应用,它会和用户的Dropbox账户互动。请问,存储这个账户的Oauth令牌(token)在一个普通文件里,最好的方法是什么?
把令牌进行哈希处理安全吗?还是说应该加密它们?如果选择加密,那你建议怎么存储加密的密钥呢?因为我们需要双向加密才能解密令牌,以便发送到Dropbox。
我可以使用sqlite来存储令牌,但我在想有没有更好的方法可以用普通文件来实现。使用Sqlite也会遇到同样的问题,因为它也是一个文件。当然,文件的权限设置会尽量限制到最低,只允许网页应用访问。
1 个回答
哈希加密不太管用,因为正如skjaidev提到的,它是单向的。
如果你担心你的文件或数据库会被盗(*), 那么加密是个好办法。不过,正如你提到的,你的应用需要有解密的钥匙,问题是该把它存在哪里。显然,把钥匙和数据放在同一个地方并不能提高安全性。请考虑以下几点:
- 当你的数据在数据库里时,安全性(很可能)比在普通文件中低。这是因为有一些数据库注入的技术可能让人读取数据库,但不一定能读取文件。在这种情况下,把解密钥匙放在文件系统的某个地方(在你的代码里)是有意义的:因为单靠数据库里的数据在这种情况下是没用的。
- 即使你的数据在普通文件中,把解密钥匙放在某个文件里也能降低风险。很多系统被“黑客”攻击是因为黑客进入了一个本不该包含这些数据的系统,那里可能有旧的备份数据,或者以其他方式不一定包含你的代码和解密钥匙。
最好的办法是把解密钥匙完全不放在文件系统里,而是直接放在计算机的内存中。虽然有经验的黑客如果有根权限或物理访问权限,还是能获取到,但我认为在99%的情况下,黑客进入文件系统后,无法读取内存(比如他们偷走备份、偷走物理机器(在这个过程中关掉它)、获得用户级别的访问权限等)。这基本上就是钥匙链的方法。问题是,如何把解密钥匙放入内存,至今我只知道一个解决办法:每次应用启动时输入它(或者输入某个解密解密钥匙的密码)。是否可接受取决于你的应用重启的频率。
还有一种方法。如果你只在用户登录你的应用时需要访问Dropbox,可以考虑用某个独特的用户属性加密令牌(例如用户登录你网站时使用的密码,或者你在第一次访问时设置的随机字符串)。在这种情况下,你也可以考虑把整个访问令牌加密存储在cookie中(而不是在你的服务器上)。
无论你选择哪种方法,正如你自己提到的,它都不会真正保护你的数据。如果你的应用能获取到解密后的令牌(如果不能,你的应用根本不需要存储它们),那么某个拥有无限权限的黑客也能做到。访问令牌的好处是,它们可能很容易被撤销,所以如果被盗了,可能也不是世界末日;而且黑客知道这些令牌可以轻易撤销,所以他们通常不会把它们当作目标。
(*) 注意:总是合理地假设东西最终会以某种方式被盗。我可以想象,如果你在家里的电脑上为20个朋友搭建一个小网站,你可能不太在意密码被盗,但如果你在建立下一个Instagram,那就另当别论了。安全性和工作量之间总是有一个权衡。如前所述,如果处理得当,把令牌放在普通文件中而不是数据库中,应该会降低被盗的可能性。