Cipher.getInstance("AES") 的正确使用方法是什么?
What is the correct way to use Cipher.getInstance("AES")?
Cipher.getInstance("AES")
AndroidStudio的Lint对上面的代码报错如下:
cipher.getinstance should not be called without setting the encryption
mode and padding
如 an SO answer 所解释的那样,上面的代码完美运行。
任何人都可以阐明如何正确使用 cipher.getinstance() 吗?
实例化 Cipher
实例时,算法、模式和填充应 始终显式 指定,例如:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
如果 仅 指定了算法,则会应用 provider-specific 模式和填充值,请参阅 Android or Java 文档中的 Cipher
。这有许多 error-prone 缺点,因此应严格避免:
- 许多提供商使用 ECB 模式和 PKCS#5 填充作为默认值,例如Android 上的 BouncyCastle 提供商(已针对 API 级别 28 和 29 进行测试)。但是,ECB 模式不安全,因此不应应用,请参阅 Why shouldn't I use ECB encryption?。要防止使用 ECB 模式,需要 显式 指定模式。
- Cross-platform 如果涉及具有不同模式和填充默认值的不同提供程序,则会出现问题。
- 模式和填充的显式规范提高了可读性。
Lint 工具通过其警告指出这些问题 Cipher.getInstance should not be called without setting the encryption mode and padding。顺便说一句,当使用 AES/ECB/PKCS5Padding
指定时,Lint 报告还警告 ECB 的不安全性:不应使用 ECB 加密模式。
相比之下,当使用 AES/CBC/PKCS5Padding
指定 CBC 时,不会在 Lint 中触发警告。
虽然 CBC 比 ECB 更安全,但 CBC 仅支持机密性。因此,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)。因此,GCM 指定为 AES/GCM/NoPadding
.
在这里您可以找到关于 CBC 和 ECB 之间区别的 post: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?。
最后,关于 PKCS#5 填充的一点说明:Java/Android 世界中由于历史原因被称为 PKCS#5 填充的实际上是 PKCS#7 填充。您可以在此处找到有关此主题的更多详细信息:What is the difference between PKCS#5 padding and PKCS#7 padding?.
Cipher.getInstance("AES")
AndroidStudio的Lint对上面的代码报错如下:
cipher.getinstance should not be called without setting the encryption mode and padding
如 an SO answer 所解释的那样,上面的代码完美运行。
任何人都可以阐明如何正确使用 cipher.getinstance() 吗?
实例化 Cipher
实例时,算法、模式和填充应 始终显式 指定,例如:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
如果 仅 指定了算法,则会应用 provider-specific 模式和填充值,请参阅 Android or Java 文档中的 Cipher
。这有许多 error-prone 缺点,因此应严格避免:
- 许多提供商使用 ECB 模式和 PKCS#5 填充作为默认值,例如Android 上的 BouncyCastle 提供商(已针对 API 级别 28 和 29 进行测试)。但是,ECB 模式不安全,因此不应应用,请参阅 Why shouldn't I use ECB encryption?。要防止使用 ECB 模式,需要 显式 指定模式。
- Cross-platform 如果涉及具有不同模式和填充默认值的不同提供程序,则会出现问题。
- 模式和填充的显式规范提高了可读性。
Lint 工具通过其警告指出这些问题 Cipher.getInstance should not be called without setting the encryption mode and padding。顺便说一句,当使用 AES/ECB/PKCS5Padding
指定时,Lint 报告还警告 ECB 的不安全性:不应使用 ECB 加密模式。
相比之下,当使用 AES/CBC/PKCS5Padding
指定 CBC 时,不会在 Lint 中触发警告。
虽然 CBC 比 ECB 更安全,但 CBC 仅支持机密性。因此,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)。因此,GCM 指定为 AES/GCM/NoPadding
.
在这里您可以找到关于 CBC 和 ECB 之间区别的 post: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?。
最后,关于 PKCS#5 填充的一点说明:Java/Android 世界中由于历史原因被称为 PKCS#5 填充的实际上是 PKCS#7 填充。您可以在此处找到有关此主题的更多详细信息:What is the difference between PKCS#5 padding and PKCS#7 padding?.