如何在Cloudant数据库中安全地存储用户密码?

时间:2016-02-09 18:14:41

标签: database authentication passwords couchdb cloudant

您应该如何在Cloudant数据库中存储用户密码?用户,我指的是使用Cloudant作为后端的应用程序的用户。

我搜索了文档,但我没有找到关于该主题的内容。 有一个_users数据库,您可以在其中创建用户并添加一个"密码"字段,但密码是数据库管理员(可能还有其他人)可以读取的常规字段。

是否有内置方法可以将其隐藏起来或加密?

修改

我找到了一块拼图,CouchDB security feature加密了用户的密码。

  

从CouchDB 1.2.0开始,password_sha和salt字段是   在用户中存在密码字段时自动创建   文献。写入用户文档时,CouchDB会检查用户文档   密码字段的存在,如果存在,它将生成一个   salt,哈希密码字段的值并散列连接   密码哈希和盐。然后写出结果   密码进入password_sha字段,盐进入盐场。   密码字段已删除。

     

这具有以下含义:客户不再需要   手动计算密码salt和hash。耶。

现在缺少的是底层数据库功能与Cloudant之间的链接(仅在用户文档中设置password字段无效)。

编辑2

发现other question与此类似 - 它是一个更广泛的问题,但专门针对网络应用。 @JasonSmith接受了一个回答我的问题的答案:

  

我可以使用CouchDB安全功能

回答"是的,你可以"

  

Cloudant尚未在服务器中使用较新的CouchDB功能   会自动为您输入密码

但CouchDB文档声明此功能包含在2013年的1.20版本中!那个"更新"特征?

从文档中我收集到Cloudant使用CouchDB 1.61。

回顾一下:

  • 该功能存在,
  • 它是Cloudant使用的CouchDB版本中存在的CouchDB安全功能,
  • 可以将Cloudant配置为使用CouchDB安全功能

所以...缺少的链接真的真的小......

3 个答案:

答案 0 :(得分:2)

正如您所发现的,Cloudant不会自动哈希密码服务器端,如Couch 1.2中所介绍的那样。此外,它只支持简单的密码方案:盐渍SHA1(您可能会发现它不足)。这就是如何保存密码(不是纯文本)。

它还错过了许多其他安全功能,例如_users数据库的特殊访问规则(描述为here)。

哈希密码"自动"可以通过更新功能完成(特殊访问规则可以通过show / list功能实现)。我自己做了这个:

function (doc, req) {

    var body = JSON.parse(req.body || '{}') || {};

    if (doc == null) doc = {
        _id: req.id,
        type: 'user'
    };

    doc.name = body.name;
    doc.roles = body.roles;
    doc.salt = req.uuid;
    doc.password_scheme = 'simple';
    doc.password_sha = hex_sha1(body.password + doc.salt);

    return [doc, { json: doc }];
}

here获取hex_sha1。在_users数据库的设计文档中将上面设置为update function。您也可以将this用作validation function

然后,不是将用户放入数据库,而是将相同的JSON输入到更新函数,并在将其提交到数据库之前生成盐渍哈希。

如果盐渍SHA1不足以满足您的目的,您不能依赖Cloudant上的_users

我不太了解你的设计,我真的无法给出太多建议。

但是我应该警告你,由于_users支持不佳,例如在Cloudant上有效实施2层架构几乎是不可能的。我很高兴与一个知道得更好的人发生矛盾,但是经过几个月的抨击(以及唠叨的支持),这就是我得出的结论。

最终,您需要一个应用层来通过_users或API密钥进行用户管理。一旦你有了这样一个层,你可以在那里散列密码,和/或跳过_users数据库并以其他方式进行用户管理。一旦事情变得足够复杂,Cloudant发布的每个样本最终都会这样做(并且没有一个样本可以扩展到成千上万的用户,顺便说一下。)

最后,对@ Anti-weakpasswords,谁说你必须使用PBKDF2和巨大的迭代计数。

这是关于保存密码的合理建议,但是:

  1. 这根本不适用于Cloudant;
  2. 它与CouchDB的合作并不是很好。
  3. 首先,如上所述,如果盐水SHA1是Cloudant支持的全部,则为。

    但即便对CouchDB来说,这也是一个糟糕的建议。使用基本的HTTP身份验证,您可以在每个请求上发送密码。对每个请求进行大量迭代计数的键拉伸会给服务器带来巨大压力,因此不推荐大量的迭代计数(这就是为什么文档中有10个)。如果您要走这条路,您需要确保始终使用_session和Cookie,并避免像瘟疫这样的基本身份验证。

    更有可能的是,如果你认真对待安全性,你需要在客户端和数据库之间建立一个层,以其他方式处理用户管理,并且使用足够强的密码将数据库用户/角色分离,根本不需要强大的散列

答案 1 :(得分:2)

Clusers刚出来!它可能对您有用。 Clusers是Cloudant和CouchDB的用户帐户创建者。它使用较旧的“password_scheme:simple”,即Cloudant和较旧的CouchDB。

答案 2 :(得分:0)

首先,你确实需要阅读Thomas Pornin's canonical answer to How to Securely Hash Passwords

立即阅读。

现在阅读CouchDB链接,并看看为1.3生成password_sha的推荐方法之一(如果你不是至少1.3,那么就到达那里)。

  

{      " _id":" org.couchdb.user:username",      " _rev":" 1-227bbe6ddc1db6826fb6f8a250ef6264",      " password_scheme":" pbkdf2",      "迭代":10,      " name":" username",      "角色":[      ]      "输入":"用户",      " derived_key":" aa7dc3719f9c48f1ac72754b28b3f2b6974c2062",      "盐":" 77bac623e30d91809eecbc974aecf807"   }

确保password_scheme是pbkdf2!

看到"迭代":10在同一个?你需要bump that up by a huge amount - 我会说尝试一个数十万的数字并看看它是如何运行的; SHA-1现在非常便宜。

就Cloudant而言,here's a Github repository使用一些代码让Cloudant使用CouchDB _users。