使用 JarSigner 与 RSASSA-PSS

huangapple go评论70阅读模式
英文:

Using the JarSigner with RSASSA-PSS

问题

我正在尝试使用JarSigner和PKCS#11对JAR文件进行RSA-PSS签名。要指定签名算法,JarSigner使用sigalg标志。JDK 14 JarSigner文档没有明确指定支持哪些sigalg。我已经测试过,JarSigner接受"RSASSA-PSS"作为有效算法。但是,JarSigner不接受"SHA256withRSASSA-PSS"或类似的RSASSA-PSS变种,而这些变种通常由Java加密服务提供程序(例如SunPKCS11加密服务提供程序)支持。

当尝试使用sigalg "RSASSA-PSS" 签名时,JarSigner返回以下异常:

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

这个异常意味着PSS参数没有设置。我已经追踪到问题出在JarSigner上:

我是否遗漏了什么?如果是的话,如何对JAR文件进行RSA-PSS签名?如果不是,这是一个Bug吗?毕竟,JarSigner明显接受RSASSA-PSS作为有效的sigalg。还是这只是JarSigner与SunPKCS11实现之间的不兼容性?毕竟,在这种情况下,SunPKCS11可能只是在硬编码PSS参数值。

英文:

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.

答案1

得分: 3

Exception in thread "main" jdk.security.jarsigner.JarSignerException: 创建签名时出错
	at jdk.jartool/jdk.security.jarsigner.JarSigner.sign(JarSigner.java:573)
	at JarSignerDemo.main(scratch_3.java:28)
Caused by: java.security.SignatureException: RSASSA-PSS 签名需要参数
	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签名。但我不确定是否对您来说是个替代选择。也许您只想切换到另一种密钥类型。


<details>
<summary>英文:</summary>

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:

```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 = &quot;changeit&quot;.toCharArray();
    KeyStore keyStore = KeyStore.getInstance(new File(&quot;keystore.jks&quot;), password);
    PrivateKey privateKey = (PrivateKey) keyStore.getKey(&quot;mykey&quot;, password);
    CertPath certPath = CertificateFactory.getInstance(&quot;X.509&quot;).generateCertPath(Arrays.asList(keyStore.getCertificateChain(&quot;mykey&quot;)));
    JarSigner jarSigner = new JarSigner.Builder(privateKey, certPath)
      .digestAlgorithm(&quot;SHA-256&quot;)
      .signatureAlgorithm(&quot;RSASSA-PSS&quot;)
      .build();
    try (
      ZipFile jarFile = new ZipFile(&quot;my.jar&quot;);
      FileOutputStream signedJarFile = new FileOutputStream(&quot;my-signed.jar&quot;)
    )
    {
      jarSigner.sign(jarFile, signedJarFile);
    }
  }
}
Exception in thread &quot;main&quot; 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.

huangapple
  • 本文由 发表于 2020年10月2日 21:11:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/64174607.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定