我有代码来创建CMS签名。它现在运行良好,我需要添加可信的时间戳。
BIO *data_output = BIO_new(BIO_s_mem());
const EVP_MD *sign_md = EVP_get_digestbyname(digest_name);
cms = CMS_sign(NULL, NULL, NULL, bio_in, flags);
BOOST_ASSERT(cms);
for (size_t i = 0; i < m_signers.size(); i++) {
int tflags = flags;
SignerInfo si = m_signers[i];
CMS_SignerInfo *signer_info = CMS_add1_signer(cms,
si.m_x509, si.m_privateKey, sign_md, tflags);
BOOST_ASSERT(signer_info != NULL);
for (int c = 0; c < sk_X509_num(si.m_ca); c++) {
X509* cert = sk_X509_value(si.m_ca, c);
BOOST_ASSERT(CMS_add0_cert(cms, cert) != 0);
}
}
BOOST_ASSERT(CMS_final(cms, bio_in, NULL, flags) != 0);
BOOST_ASSERT(i2d_CMS_bio_stream(data_output, cms, bio_in, flags) != 0);
为了与TSA交谈,我需要摘要值,但在调用CMS_final之前无法获取摘要值。我无法在任何地方找到答案。
答案 0 :(得分:0)
id-aa-timeStampToken是未签名的属性。如果您的实现之后没有钩子可以修改消息,则可以分两次进行。请调用final,获取哈希并将其发送到TSA。然后构建另一个相同的CMS,并添加一个未签名的id-aa-timeStampToken属性(OID 1.2.840.113549.1.9.16.2.14)。在其中粘贴timestampToken并调用final。
请注意,使用时间戳通常需要SIGNED属性签名时间Pkcs9SigningTime(OID 1.2.840.113549.1.9.5),因此可以节省第一次获取两个相同CMS消息所用的时间。
它有点便宜,但是可以完成工作。如果您需要在智能卡上输入图钉,它将询问两次。