java - 将 JarSigner 与 RSASSA-PSS 结合使用

标签 java cryptography pkcs#11 jarsigner

我正在尝试使用 PKCS#11 使用 JarSigner 对 JAR 文件进行 RSA-PSS 签名。 JarSigner 使用 sigalg 标志来指定签名算法。 JDK 14 Docs of the JarSigner没有指定明确支持哪些信号。我已经测试过 JarSigner 接受“RSASSA-PSS”作为有效算法。 JarSigner 不接受 Java 加密服务提供程序(例如 SunPKCS11 加密服务提供程序)通常支持的“SHA256withRSASSA-PSS”或类似的 RSASSA-PSS 变体。
当尝试使用 sigalg "RSASSA-PSS"签名时,JarSigner 返回jarsigner: unable to sign jar: java.security.SignatureException: Parameters required for RSASSA-PSS signature此异常意味着未设置 PSS 参数。我已将问题追溯到 JarSigner

  • 无法通过命令行传递 PSS 参数(请参阅 JDK 14 Docs of the JarSigner )
  • 从不设置 PSS 参数 - JarSigner.java从不直接(参见第 831 到 843 行)或间接(参见 Signature.javaP11PSSSignature.java)调用 setParameter->setEngineParameter->setSigParams,它负责设置所需的 PSS 参数。

  • 我错过了什么吗?如果是,我如何对 JAR 文件进行 RSA-PSS 签名?如果没有,这是一个错误吗?毕竟,JarSigner 明确接受 RSASSA-PSS 作为有效信号。或者这是 JarSigner 和 SunPKCS11 实现之间的不兼容?毕竟,在这种情况下,SunPKCS11 可能只是使用硬编码的 PSS 参数值。

    最佳答案

    似乎尚不支持此功能。我可以用 jarsigner 重现这种行为命令行工具和 Java 代码如下:

    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
    
    它看起来像 JDK-8245274旨在将此功能添加到 Java 16。我不是 100% 确定,但它看起来像您的问题。你可能想看。

    更新:有点跑题,但看起来您可以使用 BouncyCaSTLe 使用 RSASSA-PSS 进行签名。不过,我不确定这是否适合您。也许您只想切换到另一种键类型。

    关于java - 将 JarSigner 与 RSASSA-PSS 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64174607/

    相关文章:

    Java StringBuilder 在调用追加之间删除新行?

    java - 在 native Wicket 项目中使用 Maven 存储库

    qt - QCryptographicHash::Sha3_256 在 Qt5.4 和 Qt5.8 中有所不同

    c++ - std::bad_alloc 使用 Botan 进行 PKCS#11

    go - Pkcs11 ECDSA 签名返回 CKR_DATA_INVALID

    java - 通过 IAIK PKCS#11 包装器生成 AES key 并显示其值

    java - 将引号中的所有文本放入 ArrayList

    python - 在 Python 中使用 SHA256 对字节字符串进行签名

    c - 在密码学、C 编程方面需要帮助

    java - 为什么 hashCode() 和 equals() 都存在