首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何确保密码散列在计算机上是安全的,而在移动设备上却不会太慢?

如何确保密码散列在计算机上是安全的,而在移动设备上却不会太慢?
EN

Security用户
提问于 2013-09-11 13:06:47
回答 3查看 6.8K关注 0票数 16

我对密码学及其实现很陌生。我正在设计一个Android应用程序,用户输入密码来检索一些加密的数据。在对可能的解决方案进行了一些研究之后,我最终得到了如下所用的bcrypt:

用户输入密码-> bcrypt(密码) ->密钥进行加密

然后将其存储在数据库中,如下所示:

SHA256(bcrypt(密码)) ->用户检查(这存储在DB中)

我曾计划在安卓系统中使用jBCrypt实现,但据我所知,bcrypt在移动电话上的速度非常慢(超过几分钟取决于所选电话/实力模型)。

我知道放慢哈希过程是bcrypt算法的核心,但是用户需要2分钟在移动设备上登录/解密是不可接受的,而普通PC上的相同操作则需要几秒钟。但是,如果我降低智能手机上的迭代次数,攻击者可以在更快的PC上强行执行。我如何调和这两个方面的问题?

编辑

我终于决定在安卓系统上试用jBCrypt,我已经在几款不同版本的手机上进行了测试。我还在家里的PC上测试了它,并编写了一个结果表:

这似乎是一个工作因素的10-11将是可接受的,但仍然是合理的安全。我将尝试实现NDK解决方案,看看是否可以改进结果。(如果我最后做了测试,我会发布结果。)

EN

回答 3

Security用户

回答已采纳

发布于 2013-09-11 13:44:19

jBcrypt是一个Java实现。安卓应用程序是用几乎-Java编写的,用于一台名为达尔维克的几乎Java虚拟机。

对于计算密集型任务,尤其是加密算法,与等效的优化C代码相比,Java会出现典型的3x减速:一个好的Java虚拟机运行一个JIT编译器,代码的性能将受到JVM必须操作的约束的限制(从字节码到本机代码的转换必须是快速和增量的,方法必须根据每次调用进行转换;其结果必须仍然适合于垃圾收集器)。在某些特定情况下,可以观察到进一步的减速,其中本机代码可以从CPU提供的额外操作代码中受益,典型的情况是在大整数(例如RSA)上进行计算,因为CPU可能提供Java代码无法使用的“扩展”乘法(64x64->128),因为Java中缺少128位整数类型。

有关哈希函数上下文(不是“密码散列”,只是“散列”)的比较彻底的实验,请参见斯皮利卜:一个在C和Java中实现大量哈希函数的库,使用“类似的优化工作”(整个批相同的开发人员),并包括各种平台类型上的措施。

现在,Android应用程序可能会有更多的减速:

  • 智能手机的CPU速度不如个人电脑快。Smartphone CPU可以达到千兆赫兹范围,但每个周期的工作量仍然比x86 CPU少--因为智能手机CPU的主要目标之一是节省电池。一部智能手机必须在进行无线电活动时能活一整天,而一台笔记本电脑可以有一个更大的电池,只需要几个小时就够了。现代智能手机效率很高,但与台式机相比仍有差距。让我们再加一个3倍的因子。
  • Dalvik不一定是目前最好的JIT编译器。相对缺乏原始肌肉意味着JIT无法应用最复杂的优化策略,因为它会使JIT翻译方法过于昂贵。
  • 到Android2.1(包括在内),Dalvik没有JIT。这是最严重的经济放缓,其他答案暗示了这一点。在Android2.1(和之前)中,Java字节码是被解释的,而不是被翻译成本机代码,这会带来很大的额外成本(比如比JIT代码慢10到20倍)。Android2.2已经有了JIT。

切换到PBKDF2不会有太大改变。如果您使用PBKDF2,一定要使用SHA-256 (或SHA-1),而不是SHA-512,因为智能手机CPU是基于ARM的,并且会对SHA-512严重依赖的64位算术操作感到非常不舒服,从而减慢您的代码--而攻击者有一台PC,它早餐吃64位操作,不会引起同样的减速。

摘要:在Android2.1(和之前的版本)上,bcrypt会非常慢。在Android2.2上,它的速度会有点快,尽管速度不如PC (比方说,速度是PC的5到10倍)。PBKDF2,间谍..。不要以一种重要的方式改变这个画面。

所有这些都是关于bcrypt的性能的。我没有以任何方式评论在加密和密码验证中正确使用bcrypt派生的秘密。实际上,当您存储“某事”以验证密码时,您不会发现该“东西”太接近用于加密的密码派生密钥。

一种“密码合理的方法”是使用bcrypt或PBKDF2计算密码散列(包括盐类、迭代和所有内容),然后使用密钥推导函数将输出扩展为满足您需要的足够的关键材料。在上下文中,获取bcrypt输出,然后使用SHA-256对其进行散列。这产生256位。将数据库中的前128位存储为“密码验证令牌”。使用另一半作为加密密钥。

PBKDF2使这个过程稍微简单一些,因为它是一个KDF,所以您可以立即请求256位密码派生的输出,而不需要额外的散列;而bcrypt的输出大小固定在192位,这可能不足以满足您的需要。

票数 10
EN

Security用户

发布于 2013-09-11 13:38:50

在跨多个平台配置密码管理器(如KeePass )时,这也是同样的困境--您关注的是哪个平台?

因为bcrypt是一个关键的派生函数,用于扩展通过可预测的人工密码的其他快速过程;如果您从侧面处理人工密码的问题,则需要解决性能问题。

有权访问由会话密钥管理的数据。当会话密钥需要重新生成时(例如,每24小时或在重新启动电话之后),则使用bcrypt(password)bcrypt(password + master key)。在会话期间,会话密钥仅以非bcrypt密码加密来保护。

或者,您可以保留bcrypt()和相关的延迟,只需改进流程的用户界面体验。

如果解密进程作为CPU上限的后台任务运行,并带有前景通知,则使用进度条和百分比标记解密状态;如果应用程序的核心目的是安全性,大多数用户会发现这是可以接受的。事实上,它甚至可能让他们觉得应用程序比超快解密更安全。

当然,如果应用程序的核心目的与安全性无关,那么如果它确实需要bcrypt()和相关移动设备延迟的安全性增强,您可能需要重新考虑它。

票数 1
EN

Security用户

发布于 2013-09-12 05:39:34

正如你所承认的,你有矛盾的要求。你想要bcrypt尽可能的昂贵,以帮助防御离线破解,同时,你希望它不要令人望而却步的合法用户在一个相对低功率的设备。

有两种方法,两种你都应该去追求。调整成本因素(或迭代),并找到一个哈希实现,使您获得最佳(最小)的攻击者/维护者比率。

降低攻击者/防御者的比率.

密码破解者,Bitweisel,,他称之为“攻击者/防御者比率”(ADR)。当防御程序以攻击者可用速度的1 / 10的方式运行bcrypt、scrypt或PBKDF2时,ADR是10比1。在您的情况下,防御程序不仅在功能较弱的设备上运行,还可能被那些在这些系统上性能不佳的编译器所困住。

我对Android还不太了解,不能为你指明正确的方向,但是你应该努力找到一些适合它的运行环境的优化方法。我不知道那是bcrypt还是PBKDF2。同样,您并不关心绝对速度,而是关心您的环境与攻击者之间的比率。

例如,使用HMAC 512的PBKDF2对您来说可能非常慢,但如果使用SHA512阻止攻击者使用GPU进行破解,这可能是值得的。所以,即使进展缓慢,这也可能会让你得到失去的不良反应。

在桌面计算机上安装一份ocl-hashcat+ (快速破解器)的副本来测试破解率,这样您就有了用于判断不同散列方案的ADR的等式的那一边。

调优成本因子

PBKDF2、bcrypt和scrypt都允许您设置工作因素。"bcrypt耗时2分钟“的语句可以通过将成本参数减少1(使其花费1分钟)或减少2(30秒)来解决。使用PBKDF2,您可以设置迭代,迭代的范围是线性的。

因此,一旦您找到了获得最佳ADR的算法和实现,然后简单地决定您的用户将容忍什么时间。如果是2秒,那么调整成本因子或迭代,使您有两分钟。

票数 0
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/42238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档