我对密码学及其实现很陌生。我正在设计一个Android应用程序,用户输入密码来检索一些加密的数据。在对可能的解决方案进行了一些研究之后,我最终得到了如下所用的bcrypt:
用户输入密码-> bcrypt(密码) ->密钥进行加密
然后将其存储在数据库中,如下所示:
SHA256(bcrypt(密码)) ->用户检查(这存储在DB中)
我曾计划在安卓系统中使用jBCrypt实现,但据我所知,bcrypt在移动电话上的速度非常慢(超过几分钟取决于所选电话/实力模型)。
我知道放慢哈希过程是bcrypt算法的核心,但是用户需要2分钟在移动设备上登录/解密是不可接受的,而普通PC上的相同操作则需要几秒钟。但是,如果我降低智能手机上的迭代次数,攻击者可以在更快的PC上强行执行。我如何调和这两个方面的问题?
我终于决定在安卓系统上试用jBCrypt,我已经在几款不同版本的手机上进行了测试。我还在家里的PC上测试了它,并编写了一个结果表:
这似乎是一个工作因素的10-11将是可接受的,但仍然是合理的安全。我将尝试实现NDK解决方案,看看是否可以改进结果。(如果我最后做了测试,我会发布结果。)
发布于 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应用程序可能会有更多的减速:
切换到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位,这可能不足以满足您的需要。
发布于 2013-09-11 13:38:50
在跨多个平台配置密码管理器(如KeePass )时,这也是同样的困境--您关注的是哪个平台?
因为bcrypt
是一个关键的派生函数,用于扩展通过可预测的人工密码的其他快速过程;如果您从侧面处理人工密码的问题,则需要解决性能问题。
有权访问由会话密钥管理的数据。当会话密钥需要重新生成时(例如,每24小时或在重新启动电话之后),则使用bcrypt(password)
或bcrypt(password + master key)
。在会话期间,会话密钥仅以非bcrypt密码加密来保护。
或者,您可以保留bcrypt()
和相关的延迟,只需改进流程的用户界面体验。
如果解密进程作为CPU上限的后台任务运行,并带有前景通知,则使用进度条和百分比标记解密状态;如果应用程序的核心目的是安全性,大多数用户会发现这是可以接受的。事实上,它甚至可能让他们觉得应用程序比超快解密更安全。
当然,如果应用程序的核心目的与安全性无关,那么如果它确实需要bcrypt()
和相关移动设备延迟的安全性增强,您可能需要重新考虑它。
发布于 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秒,那么调整成本因子或迭代,使您有两分钟。
https://security.stackexchange.com/questions/42238
复制相似问题