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 is the existing KeyStore.PrivateKeyEntry. Supply proxy account values from the application's credential source, then use this signer in its normal ZipFile/output-stream workflow.

The requestor-type predicate keeps proxy and destination authentication separate, preventing a destination challenge receiving the proxy password; host and port restrict the intermediary.

System properties and the default Authenticator affect the whole JVM. Set their lifetime at startup instead of switching them around concurrent jobs.

The public jdk.security.jarsigner API avoids sun.security.tools.jarsigner.Main and old tools.jar layouts. The example uses HTTP TSA; HTTPS TSA also needs its HTTPS route and normal verification/authentication policy.

Allakkat attuumassuteqartut