2016-02-09 102 views
2

你应该如何将用户密码存储在Cloudant DB中?对于用户,我指的是使用Cloudant作为后端的应用程序的用户。如何安全地将用户密码存储在Cloudant DB中?

我搜索的文档,但我发现这个主题无关。 有一个_users数据库,在其中您可以创建用户并添加“密码”栏,但密码是一个普通的字段,数据库管理员(可能还有其他人)能读。

有没有办法将其隐藏或加密它内置的方式吗?

(后)为抢占“刚DIY”编辑答案

我得到一些“那是你的工作”的意见和答案是 - 在我看来 - 跑题了。请考虑一个现实检查,谁是像Cloudant这样的服务的目标受众,其入门门槛很低?懒惰的客户端开发人员喜欢我。投掷PBKDF2发电机并没有解决问题。突然,事情变得很多更加复杂,“公正”的安全功能。现实生活中会发生什么?密码将以纯文本形式存储,因为选择是:

A)您将应用程序的密码以纯文本形式存储在除了您(管理员)和其他未来的俄罗斯黑客都无法看到的地方

B),因为你忙于研究如何散列密码123456为他们写上后,它和电子邮件

送他们,如果你选择了B中的用户你不发货您的应用程序,这很好,但是你不是目标受众

而且不管底层数据库,服务器必然已经有一些(好,跟上时代的,测试)散列功能的工作,因为它需要它管理员密码。所以这只是一个以某种形式向客户提供的问题。

编辑

我发现一块拼图,即加密用户密码CouchDB security feature

由于CouchDB的1.2.0,在password_sha和盐字段 时自动创建一个密码字段是存在于用户 文件内。当用户文件被写入,CouchDB的检查的存在 密码字段,并且如果存在,它会产生一个 盐,哈希密码字段的值和散列密码散列和盐的级联 。然后它将生成的 密码写入password_sha字段,并将盐写入salt字段。 密码字段已删除。

这具有以下含义:客户不再需要 手动计算密码salt和散列值。好极了。

现在缺少了什么是潜在的DB的特征和Cloudant(只需设置password领域的用户文档中不工作)之间的联系。

编辑2

研究发现,other question其类似于这一个 - 这是一个广泛的问题,但专门为网络应用。有来自@JasonSmith,解决我的问题一个公认的答案:

我可以使用CouchDB的安全功能

答案是“是的,你可以”

Cloudant还没有较新的CouchDB功能,其中服务器 将自动为你输入密码

但是CouchDB文档声明,这个特性包含在2013年的1.20版本中!那是一个“更新”的功能?

从文档中,我了解到Cloudant使用CouchDB 1.61。

总结一下:

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

所以......缺失的环节确实是真的小...

+1

云是无关紧要的。你的问题是*如何安全地存储用户密码*期间。答案是密码学。 PBKDF2(基于密码的密钥派生函数2)https://en.wikipedia.org/wiki/PBKDF2 –

+0

我不同意。 Cloudant是一项服务,而不仅仅是一个数据库。它可以(并且在我看来应该,因为它是一个基本功能)处理它(例如我目前使用的BaaS)。即使对于数据库,也可以存在“密码”字段类型。即使没有处理,它也可以提供一些实用程序。 – Ilya

+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上有效实施两层架构。我会很高兴能被一个更好的人知道,但几个月后,我的头撞到这个头上(和唠叨的支持),这是我得出的结论。

最终,您需要一个应用程序层来执行用户管理,通过_users或API密钥。一旦你有了这样一个图层,那你就可以散列密码,并且/或者跳过_users数据库并以其他方式进行用户管理。 Cloudant发布的每个示例最终都会这样做,只要事情变得复杂一点(并且没有一个示例可以扩展到数以万计的用户,反之亦然)。


最后,@反weakpasswords,谁说,你必须用PBKDF2和巨大的迭代次数去。

这是关于一般保存密码中肯的意见,但:

  1. 这并不Cloudant工作,在所有;
  2. 它实际上并不适用于CouchDB。

首先,如上所述,如果盐腌的SHA1是Cloudant支持的所有期间。

但即使对于CouchDB,这也是不好的建议。通过基本的HTTP验证,您可以在每个请求上发送密码。在每次请求中使用大量迭代计数的关键将给服务器带来巨大的压力,因此不建议大量迭代(这就是为什么文档中有10个)的原因。如果你走的是这条路,你需要确保你总是使用_session和cookies,并避免像瘟疫这样的基本认证。

更有可能的是,如果您认真对待安全问题,您需要在客户端和数据库之间建立一个以其他方式处理用户管理的数据库层,并使用足够强大的密码解除数据库用户/角色的绑定,所有。

+0

感谢您的回答,但我有几个问题。首先“哈希密码”自动“可以通过更新功能来完成”=>是否记录在案? – Ilya

+1

查看上面的更新。设计文档的完整代码在这里发布太多了。 –

+0

好吧,所以你在服务器端编码,只有sha1在更新函数中可用(正确?),但解码怎么样? – Ilya

0

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

立即阅读。

现在阅读CouchDB链接,并参阅推荐的方法来为1.3生成password_sha(如果您不在1.3以上,请到此处)。

{ “_id”: “org.couchdb.user:用户名”, “_rev”: “1-227bbe6ddc1db6826fb6f8a250ef6264”, “password_scheme”: “PBKDF2”, “迭代”:10, “名称”: “用户名”, “角色”:[ ], “类型”: “用户”, “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。

+0

感谢所有的信息,我会看看链接。但你的回答是IMO的观点,所以我已经更新了这个问题来解决它。 – Ilya

+0

@Ilya,你看过最后一个链接,Github存储库中有代码让Cloudant使用CouchDB _users吗? –

+0

我做过了,但Cloudant已经可以使用CouchDB _users ...?除此之外,他说:“大部分工作都可以在一个普通的CouchDB实例上运行,但是Cloudant需要在创建用户时包含salt和sha1哈希密码。” – Ilya

2

Clusers刚出来!它可能对你有用。 Clusers是一个用于Cloudant和CouchDB的用户帐户创建者。它使用了旧版的“password_scheme:simple”,它是Cloudant和较早的CouchDB。

+0

感谢您的信息 – Ilya

相关问题