1

我想要的是

以标准格式(CMS / CAdES-EPES)创建分离的数字签名。

我现在如何创建数字签名

我从文档 (SHA-256) 创建哈希,获取哈希算法 ID 并将其全部放入一条消息中,该消息发送到智能卡 (JavaCard)。为此消息(RSA-512)生成分离的签名并发送回。我可以使用纯 Java(到目前为止还没有 BouncyCastle)使用代码验证此签名:

RSAPublicKey pubK = (RSAPublicKey) cert.getPublicKey();
Signature sig = Signature.getInstance("SHA256withRSA", "BC");
sig.initVerify(pubK);
//load signed file and update sig
...
sig.verify(signedMessage)

问题

我的目标是从已签名的数据中获取 CMS(PKCS#7) 签名。悬停,如此处所述->如果我有证书,我们如何将 PKCS#1 转换为 PKCS#7?- 由于签名属性,“转换”为 CMS 并不容易。好吧,让我们说,无论如何我都想尝试一下(只是为了有备份解决方案)。首先,我尝试使用 BouncyCastle。但是,我找不到使用已签名数据且无法访问主键的方法(因为它在智能卡上,因此无法导出)。所以我尝试了这样的原生java库:

X500Name xName = X500Name.asX500Name(cert.getSubjectX500Principal());
BigInteger serial   = cert.getSerialNumber();
AlgorithmId digestAlgorithmId = new AlgorithmId(AlgorithmId.SHA512_oid);
AlgorithmId signAlgorithmId = new AlgorithmId(AlgorithmId.RSAEncryption_oid);

//SignerInfo
SignerInfo sInfo = new SignerInfo(xName, serial, digestAlgorithmId, signAlgorithmId, signatureBytes);
//Create ContentInfo
ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));
//create PKCS7 signature
PKCS7 p7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo,
        new java.security.cert.X509Certificate[] { cert },
        new SignerInfo[] { sInfo });
//Write PKCS7 to bYteArray
ByteArrayOutputStream bOut = new DerOutputStream();
p7.encodeSignedData(bOut);
byte[] encodedPKCS7 = bOut.toByteArray();

老实说,这种方法对我来说似乎“不正确”,我什至无法使用 PKCS7.verify() 方法对其进行验证(它返回 null,这是不成功的验证并且不会引发异常)。

所以我的问题是:

  1. 有没有办法直接从 JavaCard 获取 CMS 签名?
  2. 是否可以仅使用签名者证书(没有访问私钥)从已经生成的签名创建 CMS 签名?
  3. 你看到上面的“转换”代码有什么问题吗?
  4. 您知道任何可用于验证分离签名的工具吗?(能够检查我的结果)

A 一直在寻找答案 2 周了,我真的很绝望。感谢您提供任何信息/帮助。

4

1 回答 1

1

(1) 有没有办法直接从 JavaCard 获取 CMS 签名?

由于 JavaCard 的用途非常广泛,如果您是对它们进行编程的人,那么这就是可能的。但是,检索这些 CMS 容器所需的通信将是非常专有的,很可能只能由您的代码(这对您可能是好或坏;对于客户来说通常是坏的)和来自破解您的解决方案的人的代码可用。

(2) 是否可以仅使用签名者证书从已经生成的签名创建 CMS 签名(不访问私钥)?

如果您已经拥有 PKCS#1 签名,则可以创建非常原始的 CMS 签名容器,参见。如果我有您所指的证书,我们如何将 PKCS#1 转换为 PKCS#7问题。

但是,如果您打算与其他签名验证软件互操作,那么这种原始签名(具有巨大的操纵潜力)很可能会被拒绝。

(3) 你看到上面的“转换”代码有什么问题吗?

还请提供样本 PKCS#1 输入签名和样本 CMS 结果。此外,正如@owlstead 评论的那样,您不应该使用 Sun 内部类,它们可能会被更改、重命名甚至删除,恕不另行通知。(实际上我更愿意将should替换为shall。)

(4) 你知道任何可以用来验证分离签名的工具吗?(能够检查我的结果)

OpenSSL 包含验证工具。此外,还有许多提供签名验证服务的 Web 服务。其中哪一个适合您,很大程度上取决于您签名的 PKI 和法律环境。

于 2013-02-27T11:47:27.627 回答