Im trying to RSA-PSS-sign a JAR file with the JarSigner using PKCS#11. To specify the signature algorithm the JarSigner uses the sigalg flag. The JDK 14 Docs of the JarSigner does not specify which sigalgs are explicitly supported. I have tested that the JarSigner accepts "RSASSA-PSS" as a valid algorithm. The JarSigner does not accept "SHA256withRSASSA-PSS" or similar RSASSA-PSS variants that Java Crypto Service Providers, such as the SunPKCS11 Crypto Service Provider, often support. When trying to sign with the sigalg "RSASSA-PSS" the JarSigner returns
jarsigner: unable to sign jar: java.security.SignatureException: Parameters required for RSASSA-PSS signature
This exception means that the PSS parameters are not set. I have traced the problem down to the JarSigner
Am I missing something? If yes, how can I RSA-PSS-sign a JAR file? If no, is this a bug? After all, the JarSigner clearly accepts RSASSA-PSS as a valid sigalg. Or is this rather an incompatibility between the JarSigner and the SunPKCS11 implementation? After all, SunPKCS11 could just be using hardcoded PSS param values in such a case.
It looks like this is not supported yet. I can reproduce this behaviour both with the jarsigner
command line tool and with Java code like this:
import jdk.security.jarsigner.JarSigner;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.zip.ZipFile;
class JarSignerDemo {
public static void main(String[] args) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
char[] password = "changeit".toCharArray();
KeyStore keyStore = KeyStore.getInstance(new File("keystore.jks"), password);
PrivateKey privateKey = (PrivateKey) keyStore.getKey("mykey", password);
CertPath certPath = CertificateFactory.getInstance("X.509").generateCertPath(Arrays.asList(keyStore.getCertificateChain("mykey")));
JarSigner jarSigner = new JarSigner.Builder(privateKey, certPath)
.digestAlgorithm("SHA-256")
.signatureAlgorithm("RSASSA-PSS")
.build();
try (
ZipFile jarFile = new ZipFile("my.jar");
FileOutputStream signedJarFile = new FileOutputStream("my-signed.jar")
)
{
jarSigner.sign(jarFile, signedJarFile);
}
}
}
Exception in thread "main" jdk.security.jarsigner.JarSignerException: Error creating signature
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign(JarSigner.java:573)
at JarSignerDemo.main(scratch_3.java:28)
Caused by: java.security.SignatureException: Parameters required for RSASSA-PSS signatures
at java.base/sun.security.rsa.RSAPSSSignature.ensureInit(RSAPSSSignature.java:295)
at java.base/sun.security.rsa.RSAPSSSignature.engineUpdate(RSAPSSSignature.java:346)
at java.base/java.security.Signature$Delegate.engineUpdate(Signature.java:1393)
at java.base/java.security.Signature.update(Signature.java:902)
at java.base/java.security.Signature.update(Signature.java:871)
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign0(JarSigner.java:841)
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign(JarSigner.java:562)
... 1 more
It looks like JDK-8245274 is meant to add this feature to Java 16. I am not 100% sure, but it looks like your issue. You may want to watch it.
Update: Slightly off-topic, but it looks like you can sign with RSASSA-PSS using BouncyCastle. I am not sure if that is an alternative for you, though. Maybe you just want to switch to another key type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With