我想要的是
以标准格式(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,这是不成功的验证并且不会引发异常)。
所以我的问题是:
- 有没有办法直接从 JavaCard 获取 CMS 签名?
- 是否可以仅使用签名者证书(没有访问私钥)从已经生成的签名创建 CMS 签名?
- 你看到上面的“转换”代码有什么问题吗?
- 您知道任何可用于验证分离签名的工具吗?(能够检查我的结果)
A 一直在寻找答案 2 周了,我真的很绝望。感谢您提供任何信息/帮助。