Utilisation de JarSigner avec RSASSA-PSS

Oct 02 2020

J'essaye de RSA-PSS-signer un fichier JAR avec le JarSigner en utilisant PKCS # 11. Pour spécifier l'algorithme de signature, JarSigner utilise l' indicateur sigalg . La documentation JDK 14 du JarSigner ne spécifie pas quels sigalgs sont explicitement pris en charge. J'ai testé que le JarSigner accepte "RSASSA-PSS" comme algorithme valide. JarSigner n'accepte pas "SHA256 withRSASSA-PSS" ou des variantes RSASSA-PSS similaires que les fournisseurs de services de cryptage Java, tels que le fournisseur de services de cryptage SunPKCS11, prennent souvent en charge. En essayant de signer avec le sigalg "RSASSA-PSS", le JarSigner retourne

jarsigner: unable to sign jar: java.security.SignatureException: Parameters required for RSASSA-PSS signature

Cette exception signifie que les paramètres PSS ne sont pas définis. J'ai retracé le problème jusqu'au JarSigner

  • n'ayant aucun moyen de passer les paramètres PSS via la ligne de commande (voir la documentation JDK 14 du JarSigner )
  • ne définissant jamais de paramètres PSS - le JarSigner.java n'appelle jamais directement (voir les lignes 831 à 843) ou indirectement (voir Signature.java et P11PSSSignature.java ) setParameter-> setEngineParameter-> setSigParams, qui est responsable de la définition des paramètres PSS requis.

Est-ce que je manque quelque chose? Si oui, comment puis-je signer RSA-PSS un fichier JAR? Si non, est-ce un bug? Après tout, le JarSigner accepte clairement RSASSA-PSS comme un sigalg valide. Ou est-ce plutôt une incompatibilité entre le JarSigner et l'implémentation SunPKCS11? Après tout, SunPKCS11 pourrait simplement utiliser des valeurs de paramètres PSS codées en dur dans un tel cas.

Réponses

3 kriegaex Oct 06 2020 at 08:47

Il semble que cela ne soit pas encore pris en charge. Je peux reproduire ce comportement à la fois avec l' jarsigneroutil de ligne de commande et avec du code Java comme ceci:

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

Il semble que JDK-8245274 est destiné à ajouter cette fonctionnalité à Java 16. Je ne suis pas sûr à 100%, mais cela ressemble à votre problème. Vous voudrez peut-être le regarder.


Mise à jour: légèrement hors sujet, mais il semble que vous puissiez signer avec RSASSA-PSS en utilisant BouncyCastle. Je ne sais pas si c'est une alternative pour vous, cependant. Peut-être souhaitez-vous simplement passer à un autre type de clé.