- 适用于 JDK 24 的 GraalVM(最新)
- 适用于 JDK 25 的 GraalVM(早期访问)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 存档
- 开发构建
JCA 安全服务在 Native Image 中
本页解释了 Native Image 对 Java 加密体系结构 (JCA) 框架的支持。
JCA 框架使用提供者架构来访问安全服务,例如数字签名、消息摘要、证书和证书验证、加密(对称/非对称分组/流密码)、密钥生成和管理以及安全随机数生成等。为了实现算法独立性和可扩展性,它依赖于反射,因此在 Native Image 中需要自定义配置。默认情况下,native-image 构建器使用静态分析来发现使用了哪些服务(详情请参阅下一节)。可以使用 -H:-EnableSecurityServicesFeature 禁用安全服务的自动注册。然后可以使用自定义反射配置文件或特性来注册特定应用程序所需的安全服务。请注意,当禁用安全提供者的自动注册时,所有提供者默认会从安全功能所需的特殊 JDK 缓存中过滤掉。在这种情况下,您必须使用 -H:AdditionalSecurityProviders 手动标记使用的提供者。
安全服务自动注册 #
此机制在 com.oracle.svm.hosted.SecurityServicesFeature 类中实现,它通过 JCA 框架中特定 API 方法的可达性来确定使用了哪些安全服务。
每个 JCA 提供者都会注册其支持算法的具体实现类。每个服务类(Signature、Cipher、Mac、KeyPair、KeyGenerator、KeyFactory、KeyStore 等)都声明了一系列 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 实现会打开用作源的 /latest/random 和 /latest/urandom 文件。这些文件通常在类初始化器中打开。为了避免捕获运行 native-image 构建器的机器的状态,这些类需要在运行时初始化。
自定义服务类型 #
默认情况下,只有 JCA 框架中指定的服务会自动注册。要自动注册自定义服务类型,可以使用 -H:AdditionalSecurityServiceTypes 选项。请注意,为了使自动注册生效,服务接口必须具有 getInstance 方法,并且名称与服务类型相同。如果依赖于不符合上述要求的第三方代码,则需要手动配置。在这种情况下,此类服务的提供者必须使用 -H:AdditionalSecurityProviders 选项明确注册。请注意,这些选项仅在非常特殊的情况下才需要,通常不需要。