这些答案在 2021 年甚至几年前都不准确。
既不需要使用 Spongy Castle 也不需要使用不同的包命名空间重新编译 Bouncy Castle,因为 Android 平台上的包名称冲突已在 Honeycomb 中解决(除非您still支持预蜂窝设备)。详细原因请参见:https://github.com/rtyley/spongycastle/issues/34 https://github.com/rtyley/spongycastle/issues/34
正确的解决方案是在您的 Android 应用程序中包含标准 Bouncy Castle 库,如下所示。
第一步是在 gradle 文件中包含必要的库。您可以从 Maven 获取标准 Bouncy Castle,无需下载 JAR 并将其签入您的项目。
使用 gradle 构建时,将以下内容添加到您的dependencies
gradle 项目文件中的部分:
// See https://www.bouncycastle.org/releasenotes.html for latest revision
implementation 'org.bouncycastle:bcpkix-jdk15to18:1.68'
implementation 'org.bouncycastle:bcprov-jdk15to18:1.68'
根据您的需求,您可能不需要实际添加官方发布的 Bouncy Castle 中的 Java 安全提供程序。如果您只想直接使用 Bouncy Castle 类,您现在就可以这样做。例如,我可以编写以下代码来构建 X500Name 对象,而无需安装安全提供程序:
X500NameBuilder nameBuilder = new X500NameBuilder();
nameBuilder.addRDN(BCStyle.PSEUDONYM, "xyz");
nameBuilder.addRDN(BCStyle.E, "[email protected] /cdn-cgi/l/email-protection");
X500Name name = nameBuilder.build();
另一方面,如果您想编写通过安全提供程序利用 Bouncy Castle 的代码,那么您应该首先将内置的 Android Bouncy Castle 安全提供程序替换为标准安全提供程序,因为 Java 不允许两个同名的安全提供程序。这应该在应用程序启动期间尽早完成:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class MyApplication extends Application {
static {
Security.removeProvider("BC");
// Confirm that positioning this provider at the end works for your needs!
Security.addProvider(new BouncyCastleProvider());
}
}
请注意,Java 安全提供程序严重依赖反射。如果您使用混淆或缩小项目,那么 Bouncy Castle 类将被不恰当地剔除或重命名,以防止您需要添加以下或类似内容proguard.pro
file:
-keep class org.bouncycastle.jcajce.provider.** { *; }
-keep class org.bouncycastle.jce.provider.** { *; }
最后,您可以编写在底层使用标准 Bouncy Castle 安全提供程序的代码:
// MD2 hash is not secure, just demonstrating...
MessageDigest md = MessageDigest.getInstance("MD2");
byte[] messageDigest = md.digest(byteData);
Since MD2
不是由任何 Android 内置安全提供程序提供的,只有当您按照上述方式添加 Bouncy Castle 安全提供程序时才会找到它。