有许多已发布的报告表明,在旧版本的Android上,我们需要提供我们自己的基于SecureRandom
的初始化向量(IV(,因为默认的不是随机的:
- 在 Java 中为 AES 生成 IV
- https://medium.com/@tiensinodev/basic-android-encryption-dos-and-don-ts-7bc2cd3335ff
- https://tozny.com/blog/encrypting-strings-in-android-lets-make-better-mistakes/
- Android 加密 API 未为 AES 生成安全 IV
相反,从 API 级别 23 开始,如果您尝试提供自己的 IV,则还必须在KeyGenParameterSpec.Builder
上调用 setRandomizedEncryptionRequired(false)
,否则您将获得"加密时不允许调用方提供的 IV"异常。
据推测,在第四代方面,Android从"糟糕"变成了"足够好"。
什么是截止值,低于该截止值我们应该生成自己的 IV 而不是使用 Android 生成的 IV?
从安全的角度来看,您应该始终提供自己的 IV,因为您可以完全控制其随机化质量,并消除一个潜在的安全弱点。
关于例外,在您看来,IV 是随机且好的。但是在Android的角度来看,您提供的IV是固定的,因此不好,API不知道它是否正确随机生成。因此,例外"Caller-provided IV not permitted when encrypting"
只是一个一般性警告,试图警告开发人员不要使用糟糕的 IV,并鼓励他们使用内置的 IV。
但是,请注意,内置 IV 只是构建 IV 的一种方法。如您所见,从 API 级别 23 开始,没有人保证其质量,因此最佳实践仍然是自己确保自己的 IV 质量。