为什么我的pbkdf2实现如此缓慢(与SQLCipher相比)?

时间:2013-03-07 10:02:39

标签: java android pbkdf2

我在Xoom平板电脑上编写了一个简单的Android应用程序,它只是将一些字符串注释存储在SQLCipher数据库中。

提示用户输入密码,该密码将由SQLCipher lib用于数据库。到目前为止,这种方法很好并且非常流畅。

现在我还实现了一个小的PBKDF2算法用于身份验证 (事实上​​,我希望将来加密一些其他文件,不能存储在数据库中)。 但就目前而言,我只是来检查我的pbkdf2算法是否正确。 我只使用了javax.crypto和java.security库。

代码段如下:

int derivedKeyLength = 128;
int iterations = 500;
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt, iterations, derivedKeyLength);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] derivedKey = f.generateSecret(spec).getEncoded();    

salt是一个16字节的随机数,由SecureRandom生成。

所以我硬编码了密钥和盐,并比较了derivedKey进行身份验证(只是一个测试用例!)

我现在的问题是,在我的Xoom上它会持续大约5秒直到派生函数完成,尽管迭代只设置为500.

AFAIK SQLCipher默认使用4000的迭代次数,如果密钥错误或正确,它会立即响应。 (如果我将迭代设置为4000,则至少需要15秒)

问题是,我实现了效率低下还是因为SQLCipher性能良好(原生NDK函数等)?

提前谢谢你 p.s:抱歉,我的英语不是很棒!

修改:

抱歉,我不够清楚: - )

我知道PBKDF2应该很慢(特定的迭代量,减慢暴力攻击),这正是我要求的原因!我想将迭代次数设置为5000(这是不可接受的,超过15秒)

我只是想知道因为,正如我所说,SQLCipher也使用PBKDF2(迭代= 4k,而我使用 500 )从给定密码中导出密钥。我最后并没有谈到使用AES进行加密,而只是关于导出密钥的差异。

当然,SQLCipher的速度似乎比自制的keyderiving功能更快,但我认为这不会有太大的区别,因为SCLCipher的PBKDF2真的能够立即发挥作用!

问候!

2 个答案:

答案 0 :(得分:8)

好的,那个(见下文)并不是你的问题,PBKDF2很慢,但应该无法缓慢,就像那些硬件上的参数所描述的那样。 Android PBE / KDF性能有一些统计信息(和提示):http://nelenkov.blogspot.com/2012/04/using-password-based-encryption-on.htmlSecretKeyFactory性能问题未知:[{3}}。

SecretKeyFactory可能使用纯Java实现。 SQLCipher 有两个相关的功能:

  • 它使用OpenSSL,编译后的本机代码(在我的桌面 OpenSSL的PBKDF2上快了近100倍 一个JVM6 SecretKeyFactory版本,用于2000次迭代,不包括JVM启动时间。我没有 比较AES的速度,似乎其他人在Android上发现它也很慢)
  • 4000迭代PBKDF2仅在数据库打开时完成,之后最多2次迭代 对于页面HMAC秘密(假设默认配置,如文档所述)

您的代码似乎是正确的,当您增加迭代时,不应该有如此大的(线性?)性能下降。 Xoom 应该使用JIT运行一个非古老的JVM,你能用Any way around awful SecretKeyFactory performance with LVL and AESObfuscator?验证性能问题吗?

<小时/> 由于预期的other code操作,PBKDF2 设计变慢(请参阅此问题的答案https://security.stackexchange.com/questions/7689/clarification-needed-for-nists-whitepaper-recommendation-for-password-based-ke)。迭代计数器可让您以安全性换取速度。

AES总是key stretching而且是 快速(intended to be fast,所选择的AES候选者在该论文中以其原始名称​​ Rijndael 引用。)

我假设您正在将PBKDF2计算时间直接与在SQLCipher数据库上执行SQL操作所花费的时间进行比较,这几乎肯定会被设计得很快。

您正在有效地比较具有不同要求的两种不同操作,因此速度差异。

答案 1 :(得分:2)

好的,我发现了问题所在。

如果我断开设备与我的电脑,它立即工作。如果我在那之后重新连接它。

现在即使迭代量为5000及以上,派生功能也只需不到一秒!!这很棒,因为我的Xoom不是所有设备中最新的!

可能是因为调试模式或其他原因,我实际上并不知道!

无论如何,多亏了先生。希望这可以帮助将来的某个人: - )