如何安全存储加密密钥?
我在考虑使用像pycrypto这样的加密库来加密我Python网络应用数据库中的字段。但是,加密算法需要一个密钥。如果我在源代码中放一个明文的密钥,那就显得很傻,因为如果有人能访问数据库文件,他们也能看到我的Python源代码。
有没有什么好的方法来保护这个密钥?或者有没有其他方法可以在应用层而不是数据库层加密数据库字段?
更新:我想保护的字段是oauth令牌。
更新:我想大概没有什么通用的方法可以避免这个问题。我觉得我还是得加密这些字段,因为数据库文件很可能会被备份和移动,这样至少可以把问题减少到一个单一的脆弱位置——查看我的源代码。
更新:这些oauth令牌需要在用户离线时用于API调用,因此在这种情况下用他们的密码作为密钥是不合适的。
3 个回答
在你决定哪种加密方法最好的时候,首先要想清楚你想保护的是什么,以及攻击者为了获取你系统中的密钥或信息会付出多大的努力。
你想通过加密来解决什么样的攻击情况呢?比如说,是不是担心数据库文件被盗了?
对称加密确实没什么用,正如你所注意到的;不过在某些情况下,使用非对称加密或者陷门函数可能会有用:
如果你的网页应用不需要读取回来的数据,那就可以使用非对称加密。比如说处理信用卡信息时:你的应用会用订单处理系统的公钥来加密数据,而这个系统是在一个不对外开放的机器上。
如果你只需要比较数据是否相等,可以使用陷门函数,比如消息摘要,最好再加一个盐值。这种方法适合那些在服务器上不应该被恢复的密码。
如果你要加密一些只需要验证(而不是记住)的信息,可以用简单的哈希算法,比如SHA,或者用单向加密的方法,比如DES或IDEA,同时加上一个盐值,这样可以防止彩虹表破解。这种方法适合用来处理密码或其他访问秘密。
提到Python和网络应用,我就想到Google App Engine(GAE),所以你可能不想在每次数据库操作时都进行加密和解密,因为在GAE上这些操作本身就比较耗费资源。
加密数据库的最佳做法是用用户自己的秘密来加密字段,但要加一个不对称的后门,这样可以用你的秘密密钥来解密用户的秘密密钥,这样你就能在需要恢复或其他情况下解密用户的密钥,而不是让任何有数据库源文件或表格访问权限的人都能解密。
这样一来,用户(或者你或可信的代理)只能获取和解密自己的信息。如果你打算通过加密来保护他们的信息,可能需要更加严格地验证用户的秘密。
在这方面,使用一个短语(而不是密码),比如“在丛林中,强大的丛林”,是一个很好的做法,可以鼓励用户。
编辑:刚看到你的更新。存储OAuth的最佳方式是给它们一个短暂的有效期,只请求你“需要”的资源,并在需要时重新请求,而不是获取长期的令牌。设计时最好是快速认证、获取访问权限然后退出,而不是把钥匙放在后门下十年。
因为如果你需要在用户上线时回忆OAuth,你可以像上面说的那样,用用户特定的秘密进行加密。你也可以从一个加密的计数器生成密钥(用用户的秘密加密),这样每次交易时实际的加密密钥都会变化,而计数器则以明文形式存储。但在使用之前,最好检查一下特定加密算法对这种模式的讨论,因为有些算法可能不太适合。