我想要什么
以标准格式创建分离的数字签名(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)签名。 Hovever,如这里提到的 - > How can we Convert PKCS#1 to PKCS #7 if I have the Certificate? - 由于签名属性,将“转换”为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,这是不成功的验证并且不会抛出任何异常)。
所以我的问题是:
A现在正在寻找2周的答案,我真的很绝望。感谢您提供任何信息/帮助。
答案 0 :(得分:1)
(1)有没有办法直接从JavaCard获取CMS签名?
由于JavaCards是一个非常通用的,如果你是编程它们的人,那也许是可能的。但是,检索这些CMS容器所需的通信将是非常专有的,很可能只能由您的代码使用(对您来说可能是好的或坏的;对于客户来说通常是坏的)以及来自黑客攻击您的解决方案的代码。
(2)是否可以仅使用签名者证书(不使用私钥)从已生成的签名创建CMS签名?
如果您已经拥有PKCS#1签名,则可以创建非常原始的CMS签名容器,参见您提到的问题How can we Convert PKCS#1 to PKCS #7 if I have the Certificate。
如果您打算与其他签名验证软件互操作,那么这种原始签名(具有巨大的操作潜力)很可能会被拒绝。
(3)您是否发现上述“转化”代码存在任何问题?
还请提供样本PKCS#1输入签名和样本CMS结果。此外,正如@owlstead评论的那样,你不应该使用Sun内部类,它们可能会被更改,重命名甚至删除而不另行通知。(我实际上更愿意替换应该通过 。)
(4)您是否知道可用于验证分离签名的任何工具? (能够检查我的结果)
OpenSSL包含验证工具。此外,还有许多提供签名验证服务的Web服务。其中哪一个适合您,在很大程度上取决于签名的PKI和法律环境。