java - Android 和 Java key 生成返回不同的结果

标签 java android encryption aes

我遇到了以下问题。我的应用程序分为两个不同的部分:1)第一部分使用 AES/CBC(Java)加密一些数据,2)第二部分必须检索数据并解密(Android)。 要生成 key ,我使用以下代码

SecureRandom saltRand = new SecureRandom(new byte[] { 1, 2, 3, 4 });
byte[] salt = new byte[16];
saltRand.nextBytes(salt);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 1024, 128);
SecretKey key = factory.generateSecret(spec);

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(key.getEncoded());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
sksCrypt = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

我的程序不需要不同的“源 key ”(字符串密码),但是只要源 key 相同,它就需要计算相同的 key 。不幸的是,程序的两部分生成的 key 不同,解密阶段失败。 关于如何解决这个问题有什么建议吗?

最佳答案

您正在使用随 secret 钥生成器从给定的输入 key Material 生成 key 。 key 派生函数是从 secret 派生 key 的函数。有一些基于密码的 key 派生函数,例如 PBKDF2,它使用密码(加上盐和特定的迭代计数)作为 secret 输入。还有一些基于 key 的 key 派生函数,例如 HKDF,它们使用 key 和可能的标签或其他输出 key 特定信息作为输入 Material 。

Java 确实为您提供了一组 PBKDF、PBKDF1 和 PBKDF2,其中 PBKDF2 是您当前使用的较新的。不幸的是,它不提供开箱即用的 KBKDF。您需要使用(轻量级)Bouncy CaSTLe API 来提供此类功能。我之所以知道,是因为我为 Bouncy 提供了各种 KBKDF 的初始实现。

不幸的是,正如您所发现的,使用 SecureRandom 作为替代 KBKDF 不起作用。 SHA1PRNG算法没有指定好;它是一个依赖于 SHA-1 安全哈希函数的函数,但仅此而已。因此,实现可以而且确实有所不同,例如 Android(松散地基于 GNU 类路径)和 Oracle 的 Java 之间。 SHA1PRNG 可能完全依赖种子,也可能不完全依赖种子。在较新的 Android 版本中,它甚至可能被完全不同的东西所取代。

由于您仅从输入 key Material 中派生单个 key ,因此您也可以直接用 SecretKeySpec 包装 key.getEncoded() 并将其用作 key 。根本不需要执行额外的 key 生成;您已经使用 PBKDF2 派生了 key 。额外的包装不会对 key Material 产生任何影响。 可能只需将算法设置为,例如“AES”

关于java - Android 和 Java key 生成返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46979469/

相关文章:

java - android 在早期 API 版本中包含 API 9 功能

Java Mysql查询结果集错误

java - 记录 net.sf.json.xml.XMLSerializer getType

android - 我可以用什么格式在android上录制并在ios上播放

android - 什么进入源代码管理?

java - 代码 Socket clientSocket = new Socket();即使在单独的线程中,Android 应用也会崩溃

c# - 如何将此 C# Rijndael 加密转换为 PHP?

encryption - 密码学:混合 CBC 和 CTR?

java - 使用加密货币进行加密。加密失败,解密正常

java - MVC 模型查看事件调度实现