You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17调用getSigners返回null求助:已签名Jar无法获取签名信息

问题分析与解决方案

你遇到的问题核心是自签名证书不被Java默认信任,以及PKIX路径验证失败导致类加载器未将签名/证书信息关联到类的ProtectionDomain中,和算法支持关系不大(jarsigner能验证通过说明签名算法是兼容的)。

核心原因

  • Java类加载器默认仅信任受信任CA签发的证书签名的Jar。自签名证书没有完整的信任链,PKIX路径构建失败意味着Java无法验证证书合法性,因此不会将签名者/证书信息注入到类的ProtectionDomain,导致你调用的getSigners()、getCertificates()返回null。
  • jarsigner提示的“jar verified”仅表示Jar签名与内容匹配(签名本身有效),但不代表证书被Java信任存储认可。

解决步骤

1. 将自签名证书导入Java信任存储

把你的自签名证书添加到Java系统信任存储(cacerts),或使用自定义信任存储:

  • 先导出Jar中的证书:
    # 查看Jar证书信息并导出
    jarsigner -verify -verbose -certs your.jar > cert_info.txt
    # 根据输出中的证书别名,从密钥库导出证书
    keytool -export -alias your-cert-alias -file your-cert.cer -keystore your-keystore.jks
    
  • 导入到系统信任存储(需管理员权限):
    keytool -import -trustcacerts -alias your-cert-alias -file your-cert.cer -keystore $JAVA_HOME/lib/security/cacerts
    
    系统默认cacerts密码为changeit。

2. 显式启用安全管理器(Java 17+需手动开启)

Java 17默认禁用安全管理器,若需类加载器自动关联签名信息,需显式开启并配置安全策略:

  • 启动程序时添加参数:
    java -Djava.security.manager=allow -Djava.security.policy=your-policy-file.policy YourMainClass
    
  • 在your-policy-file.policy中配置签名权限:
    grant signedBy "your-cert-alias" {
        permission java.security.AllPermission;
        // 可根据需求设置更细粒度的权限
    };
    

3. 直接解析Jar获取签名信息(绕过类加载器限制)

若不想修改信任存储或安全策略,可直接读取Jar文件提取签名与证书:

import java.io.IOException;
import java.security.cert.Certificate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarSignatureParser {
    public static void main(String[] args) throws IOException {
        try (JarFile jarFile = new JarFile("your-target.jar")) {
            // 指定要检查的类文件路径
            JarEntry classEntry = jarFile.getJarEntry("com/your/package/YourClass.class");
            Certificate[] certs = classEntry.getCertificates();
            if (certs != null) {
                for (Certificate cert : certs) {
                    System.out.println("证书类型: " + cert.getType());
                    System.out.println("证书详情:\n" + cert.toString());
                }
            }
        }
    }
}

4. 确认签名算法兼容性

虽然jarsigner验证通过,仍可检查签名算法是否在Java 17允许范围内:

  • 打开$JAVA_HOME/conf/security/java.security文件,查看jdk.jar.disabledAlgorithms配置项,确保你使用的签名算法(如SHA256withRSA)不在禁用列表中。

内容的提问来源于stack exchange,提问作者Multicoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:52:43