System.setProperty("http.proxyHost", "proxy.example");
System.setProperty("http.proxyPort", "8080");

java.net.Authenticator.setDefault(new java.net.Authenticator() {
    @Override
    protected java.net.PasswordAuthentication getPasswordAuthentication() {
        if (getRequestorType() == RequestorType.PROXY
                && "proxy.example".equalsIgnoreCase(getRequestingHost())
                && getRequestingPort() == 8080) {
            return new java.net.PasswordAuthentication(
                proxyUser, proxyPassword.toCharArray());
        }
        return null;
    }
});

var signer = new jdk.security.jarsigner.JarSigner.Builder(signingEntry)
    .tsa(java.net.URI.create("http://tsa.example/"))
    .build();

signingEntry 就是现有的 KeyStore.PrivateKeyEntry。从应用的凭据来源提供代理账号值,然后在其常规的 ZipFile 与输出流工作流中使用该签名器。

请求方类型判定将代理认证与目标认证区分开来,避免目标发起的质询拿到代理口令;主机和端口则限定中间转发者。

系统属性和默认 Authenticator 会影响整个 JVM。应在启动时设定其生命周期,而不是在并发任务之间来回切换。

公开的 jdk.security.jarsigner API 避开了 sun.security.tools.jarsigner.Main 和旧的 tools.jar 布局。示例使用 HTTP TSA;HTTPS TSA 同样需要其 HTTPS 路由以及常规的校验与认证策略。

相关文章