我遇到了以下问题。我的应用程序分为两个不同的部分:1)第一部分使用AES / CBC(Java)加密一些数据,2)第二部分必须检索数据并解密(Android)。 要生成密钥,请使用以下代码
instance FromJSON Car
我的程序不需要使用不同的“源密钥”(字符串密码),但只要源密钥相同,它就需要计算相同的密钥。遗憾的是,程序的两个部分生成的密钥是不同的,并且解密阶段失败。 关于如何解决这个问题的任何建议?
答案 0 :(得分:2)
您正在使用随机密钥生成器从给定的输入密钥材料生成密钥。 密钥派生函数是从秘密中派生密钥的函数。有基于密码的密钥派生函数,如PBKDF2,它使用密码(加上盐和特定的迭代计数)作为秘密输入。还有一些基于密钥的密钥派生函数,如HKDF,它使用密钥,可能还有标签或其他输出密钥特定信息作为输入材料。
Java确实为您提供了一组PBKDF,PBKDF1和PBKDF2,其中PBKDF2是您当前使用的较新的PBKDF2。不幸的是,它并没有提供开箱即用的KBKDF。您需要使用(轻量级)Bouncy Castle API来提供此类功能。我知道,因为我为Bouncy提供了各种KBKDF的初步实施。
不幸的是,使用SecureRandom
替换KBKDF并不起作用,因为您已经发现了。 SHA1PRNG算法没有很好地指定;它是一个依赖于SHA-1安全散列函数的函数,但这就是全部。因此,实现可以并且确实不同,例如在Android(松散地基于GNU类路径)和Oracle的Java之间。 SHA1PRNG可能完全依赖种子,也可能不完全依赖种子。在较新的Android版本中,它甚至可能被完全不同的东西取代。
由于您只从输入密钥材料中派生出一个密钥,因此您可以直接用key.getEncoded()
包裹SecretKeySpec
并将其用作密钥。根本不需要执行额外的密钥生成;你已经使用PBKDF2派生了一个密钥。额外的包装对键控材料没有任何作用。 可能只需要将算法设置为"AES"
。