使用外部生成签名通过BC库构造CMSSignedData的方案正确性咨询
方案正确性确认
你的实现是完全可行的,setDirectSignature(true)的配置是该场景下的标准用法,没有问题。
原理说明
最初实现失败的原因
默认情况下,BC库的JcaSignerInfoGeneratorBuilder会执行标准CMS签名生成流程:
- 调用
ContentSigner.getOutputStream()获取输出流 - 将待签名的原文、CMS规定的签名属性(如消息摘要、签名时间等)依次写入该输出流
- 调用
ContentSigner.getSignature()获取最终签名值,填充到SignerInfo结构中
你自定义的ContentSigner直接返回了预先生成的签名值,没有处理BC写入输出流的待签名数据,导致最终生成的CMS结构中,签名值和待校验的内容不匹配,因此验证失败。
setDirectSignature(true)的作用
该配置的核心作用就是跳过BC内部的签名计算流程:
- 通知BC不需要再往
ContentSigner的输出流写入任何待签名数据,也不需要触发内部签名计算 - 直接将
ContentSigner.getSignature()返回的预生成签名值作为最终结果,填充到SignerInfo的签名字段中 - 该设计本来就是BC提供给外部预生成签名场景的专用配置,完全匹配你的使用需求。
使用注意事项
- 必须保证预生成签名时使用的算法,和传入
ContentSigner的AlgorithmIdentifier完全一致,否则会出现算法不匹配导致验证失败 - 该方案仅适用于无签名属性的裸签名场景,如果你需要在CMS结构中添加签名时间、自定义业务属性等签名属性,需要外部生成签名时就将对应的CMS签名属性结构纳入签名范围,否则签名会验证失败。
内容的提问来源于stack exchange,提问作者SME
相关产品推荐
相关产品推荐

