使用cipher.getInstance的正确方法是什么?

发布于 2025-01-19 03:59:27 字数 298 浏览 1 评论 0 原文

Cipher.getInstance("AES")

Android Studio 的 Lint 对上述代码的抱怨如下:

在未设置加密的情况下不应调用 cipher.getinstance 模式和填充

上面的代码完美地按照 一个 SO 答案 的解释。

有人能阐明如何正确使用 cipher.getinstance() 吗?

Cipher.getInstance("AES")

Android Studio's Lint complains about the above code as follows:

cipher.getinstance should not be called without setting the encryption
mode and padding

The above code works perfectly as explained by an SO answer.

Could anyone shed some light on how to use cipher.getinstance() correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北斗星光 2025-01-26 03:59:27

实例化Cipher实例时,算法、模式和填充应始终显式指定,例如:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

如果指定了算法,则提供者-应用模式和填充的特定值,请参阅 中的 Cipher AndroidJava 文档。这有许多容易出错的缺点,因此应严格避免:

  • 许多提供程序使用 ECB 模式和 PKCS#5 填充作为默认值,例如 Android 上的 BouncyCastle 提供程序(针对 API 级别 28 和 29 进行测试)。但是,ECB 模式不安全,因此不应应用,请参阅为什么不应使用 ECB 加密?。为了防止使用 ECB 模式,需要显式指定该模式。
  • 如果涉及具有不同模式和填充默认值的不同提供程序,则可能会出现跨平台问题。
  • 模式和填充的显式规范提高了可读性。

Lint 工具通过警告指出了这些问题,在未设置加密模式和填充的情况下不应调用 Cipher.getInstance。顺便说一句,Lint 报告还警告了使用 AES/ECB/PKCS5Padding 指定 ECB 时的不安全性:不应使用 ECB 加密模式

相反,当使用 AES/CBC/PKCS5Padding 指定 CBC 时,不会在 Lint 中触发警告。


虽然 CBC 比 ECB 更安全,但 CBC 只支持机密性。因此,应首选经过身份验证的加密,它除了保密性之外还提供真实性和完整性,例如GCM。由于 GCM 基于 CTR,即流密码模式,因此不需要填充,这与 ECB 或 CBC 等分组密码模式不同(参见 块密码操作模式)。因此,GCM 是用 AES/GCM/NoPadding 指定的。

在这里您可以找到一篇有关 CBC 和 ECB 之间差异的帖子:我的分组密码应该使用 ECB 还是 CBC 加密模式? 这里关于 CBC 和 GCM 之间的区别:CBC 和 GCM 模式之间有什么区别?

最后,关于 PKCS#5 填充的一点说明:由于历史原因,Java/Android 世界中所谓的 PKCS#5 填充实际上是 PKCS#7 填充。您可以在此处找到有关此主题的更多详细信息:PKCS#5 填充和 PKCS#7 填充之间有什么区别?

When instantiating a Cipher instance, algorithm, mode, and padding should always be explicitly specified, e.g.:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

If only the algorithm is specified, provider-specific values for mode and padding are applied, see Cipher in the Android or Java documentation. This has a number of error-prone disadvantages and should therefore strictly be avoided:

  • Many providers use ECB mode and PKCS#5 padding as default values, e.g. the BouncyCastle provider on Android (tested for API level 28 und 29). However, ECB mode is insecure and should therefore not be applied, see Why shouldn't I use ECB encryption?. To prevent the use of ECB mode, the mode needs to be explicitly specified.
  • Cross-platform problems can occur if different providers with different default values for mode and padding are involved.
  • Explicit specification of mode and padding improves readability.

The Lint tool points out these problems with its warning Cipher.getInstance should not be called without setting the encryption mode and padding. By the way, the Lint report also warns about the insecurity of ECB when it is specified with AES/ECB/PKCS5Padding: ECB encryption mode should not be used.

In contrast, CBC, when specified with AES/CBC/PKCS5Padding, does not trigger a warning in Lint.


Although CBC is more secure than ECB, CBC only supports confidentiality. Therefore, authenticated encryption, which provides authenticity and integrity in addition to confidentiality, should be preferred, e.g. GCM. Since GCM is based on CTR, i.e. a stream cipher mode, no padding is required, unlike block cipher modes such as ECB or CBC (see Block cipher mode of operation). Thus, GCM is specified with AES/GCM/NoPadding.

Here you can find a post regarding the difference between CBC and ECB: Should I use ECB or CBC encryption mode for my block cipher? and here regarding the difference between CBC and GCM: What is the difference between CBC and GCM mode?.

Finally, a little note about PKCS#5 padding: what is called PKCS#5 padding in the Java/Android world for historical reasons is actually PKCS#7 padding. Here you can find more details about this topic: What is the difference between PKCS#5 padding and PKCS#7 padding?.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文