原生镜像中的 JCA 安全服务

此页面介绍了对 Java 加密架构 (JCA) 框架的原生镜像支持。

JCA 框架使用提供者架构来访问安全服务,例如数字签名、消息摘要、证书和证书验证、加密(对称/非对称分组/流密码)、密钥生成和管理以及安全随机数生成等。为了实现算法独立性和可扩展性,它依赖于反射,因此它需要在原生镜像中进行自定义配置。默认情况下,native-image 构建器使用静态分析来发现使用哪些服务(有关详细信息,请参见下一节)。可以使用 -H:-EnableSecurityServicesFeature 禁用安全服务的自动注册。然后,可以使用自定义反射配置文件或功能来注册特定应用程序所需的安全性服务。请注意,当禁用安全提供者的自动注册时,默认情况下,所有提供者都会从安全性功能所需的特殊 JDK 缓存中过滤掉。在这种情况下,您必须使用 -H:AdditionalSecurityProviders 手动标记已使用的提供者。

安全服务自动注册 #

该机制是在 com.oracle.svm.hosted.SecurityServicesFeature 类中实现的,它使用 JCA 框架中特定 API 方法的可达性来确定使用哪些安全服务。

每个 JCA 提供者都会为其支持的算法注册具体的实现类。每个服务类(SignatureCipherMacKeyPairKeyGeneratorKeyFactoryKeyStore 等)都声明了一系列 getInstance(<algorithm>, <provider> 工厂方法,这些方法提供了具体的服务实现。当请求特定算法时,框架会在已注册的提供者中搜索相应的实现类,并为具体的服务实现动态分配对象。native-image 构建器使用静态分析来发现使用哪些服务。它是通过为每个 getInstance() 工厂方法注册可达性处理程序来实现的。当它确定在运行时可以访问 getInstance() 方法时,它会自动执行相应服务类型所有具体实现的反射注册。

可以使用 -H:+TraceSecurityServices 启用安全服务自动注册的跟踪。该报告将详细说明所有已注册的服务类、触发注册的 API 方法以及每个可访问 API 方法的解析上下文。

注意:--enable-all-security-services 选项现在已弃用,将在将来的版本中删除。

提供者注册 #

native-image 构建器会从底层 JVM 中捕获提供者列表及其优先级顺序。提供者顺序在 <java-home>/conf/security/java.security 下的 java.security 文件中指定。不能在运行时注册新的安全提供者;所有提供者都必须在可执行文件构建时静态配置。

运行时提供者重新排序 #

可以在运行时重新排序安全提供者,但是只能使用现有提供者实例。例如,如果在构建时注册了 BouncyCastle 提供者,并且您希望在运行时将其插入到位置 1

Provider bcProvider = Security.getProvider("BC");
Security.removeProvider("BC");
Security.insertProviderAt(bcProvider, 1);

SecureRandom #

SecureRandom 实现会打开 /dev/random/dev/urandom 文件,这些文件用作来源。这些文件通常在类初始化器中打开。为了避免从运行 native-image 构建器的机器上捕获状态,这些类需要在运行时初始化。

自定义服务类型 #

默认情况下,只会自动注册 JCA 框架中指定的服务。若要自动注册自定义服务类型,可以使用 -H:AdditionalSecurityServiceTypes 选项。请注意,要使自动注册起作用,服务接口必须具有 getInstance 方法,并且名称必须与服务类型相同。如果依赖于不符合上述要求的第三方代码,则需要手动配置。在这种情况下,必须使用 -H:AdditionalSecurityProviders 选项显式注册此类服务的提供者。请注意,这些选项仅在非常特殊的情况下需要,通常不需要。

进一步阅读 #

联系我们