我正在生成一个带有签名的PDF文档,我希望它启用LTV。为此,我在创建PDF时对其进行签名,然后添加包含DSS的第二个版本,其中包含与验证相关的信息(VRI)。正如我在一些文章中发现的,我需要添加证书链(没有根证书颁发机构)和证书吊销列表(CRL)。在我的例子中,两者都有两个元素。之后,我添加了VRI条目,它是签名内容(在/Contents中的第一个PDF版本中找到)的SHA-1散列,其值引用上述证书和CRL。
对于证书和吊销列表元素,我都使用内容的原始字节流。
这是我的PDF样本
编辑
我获取CRL信息的方式是使用WynCrypt,如下所示:
//Retrieve chained certificate
if(!CertGetCertificateChain(hChainEngine, pSignerCert, pTime, hAdditionalStore, &chainPara, dwFlags, NULL, &ppChainContext))
return NULL;
//first cert in chain is the end cert; last one is the root cert
for(int i = 0; i < ppChainContext->cChain; ++i)
{
PCERT_SIMPLE_CHAIN simpleChain = ppChainContext->rgpChain[i];
for(int j = 0; j < (int)simpleChain->cElement - 1; j++)//do not include root certificate
{
PCERT_CHAIN_ELEMENT chainElement = simpleChain->rgpElement[j];
if(chainElement->pCertContext)
{
//the certificate bytes
byte* certBytes =chainElement->pCertContext->pbCertEncoded
}
if(chainElement->pRevocationInfo && chainElement->pRevocationInfo->pCrlInfo)
{
PCCRL_CONTEXT crlContext = chainElement->pRevocationInfo->pCrlInfo->pBaseCrlContext;//get revocation context
//the bytes that will be written in PDF
byte* crlBytes = crlContext->pbCrlEncoded;
}
}
}
解决这个问题的方法是一样的:另一个问题
刚才快速查看了一下,对象15和16是OCSP响应,但您将它们添加为CRL:
流对象15
流对象16
这是ASN。1解码器非常方便!
在我的源代码查看器中,DSS字典(对象21)是:
<<
/CRLs 19 0 R
/Certs 20 0 R
/VRI 18 0 R
>>
19点指向数组原子:[15 0 R 16 0 R]
同样,对于LTV来说,VRI不是必需的,它目前基本上是一种优化(参见ETSI TS 102 778-4中的附录A1,该附录基本上取自PDF 2.0规范)。如果使用它并添加时间戳(/TS entry),Adobe目前甚至无法正确显示它。在VRI中,TU/TS也是完全可选的,不影响LTV的有效性(同上)。
据我所知,“LTV启用”一词的含义没有正式规范。其中有一些非规范性描述,尤其是:
>
启用LTV意味着验证文件(减去根证书)所需的所有信息都包含在中。
(2013年1月10日的iText邮件列表)
另一位Adobe员工史蒂文。Madwin将实现描述为
作为验证过程的一部分,[Acrobat]会确定是否必须在线下载撤销信息,或者所有撤销信息是否都嵌入到PDF文件中。此时,它知道它将在签名导航面板中显示什么。如果必须下载数据,则签名未启用LTV,但如果文件中包含所有撤销抵押品,则签名已启用LTV。
(2013年9月24日Adobe支持论坛)
因此,术语“LTV启用”的含义取决于Adobe Acrobat签名验证算法的实现细节(这些算法是闭源的,不一定是固定的)和底层配置。你可以在多个旧堆栈溢出答案中读到我对此的咆哮...
尽管如此,这些实现细节下的机制并不是完全任意的,它们基本上形成了关于这一主题的现有发布规范的一个轮廓(尽管是专有的、封闭的,甚至可能是变化的),特别是RFC。
特别是,为了有一个很好的机会将您的签名标记为“LTV启用”,您应该做些什么,添加验证器在验证过程中可能需要的所有信息,特别是
id-pkix-ocsp-nocheck
扩展名的证书,或者您已经有它们的撤销信息)等等。然而,一个挑战仍然存在,那就是确定如何准确地将所有这些信息添加到PDF中。
如果您在签名之前知道签名者证书,则可以将所有证书添加到签名容器中的证书存储中,以创建所有吊销数据,并将所有吊销数据添加到其中的SignerInfo
的signedadbe revocationfoarchive
属性中。
如果没有,您可以将这些证书和吊销信息放入PAdES文档安全存储(DSS)中,即在已签名PDF的增量更新中放入特殊结构中。ISO 32000-1中尚未定义该DSS;它最初是在ETSI技术规范(ETSI TS 102 778-4)和后来的规范(ETSI EN 319 142-1)中定义的,并已被采用到当前的PDF规范ISO 32000-2中。
您的PDF使用DSS存储证书和吊销信息,但其中存在缺陷。
正如Peter G在他的回答中已经解释的那样,您的PDF在CRL和CRL数组中的DSS不包含实际的CRL。
正如Peter G所说,其中的对象不仅仅是OCSP响应,而是包含在其他结构中的OCSP响应。这些对象中的实际OCSP响应从偏移量160开始。。。
我猜你的代码在那个crlContext-
两年前,我也构建了一个LTV启动器。当时的实验表明,Adobe Acrobat需要某些指定为可选的DSS元素,至少在某些情况下是这样:我使用Adobe Acrobat启用了LTV,然后一步一步地将该PDF简化为我构建的东西。事实证明,VRI DSS子部分和其中的TU条目是必要的,删除其中任何一个都使文件不启用LTV。
我现在使用我的那个LTV enabler(实际上是一个可以获得额外证书的变体)来启用PDF的LTV。这奏效了。出于兴趣,我还减少了这个支持LTV的PDF。有趣的是,我可以在不丢失LTV启用状态的情况下删除TU甚至VRI。
因此,要么Adobe Acrobat已经改变为不再需要这些元素,要么我在以前的实验中开始使用的文件是一个需要额外数据的特殊情况,而在其他情况下则不需要这些数据。
然而,我想使用相同的文件,这意味着我不再假装复制PDF了。我要抓取文档,签名,并覆盖原来的。 由于我了解到让FileInputStream和FileOutputStream指向同一个文件不是一个好主意,所以我只是尝试使用file类。 我尝试了以下操作:
据我所知有两种方法 添加DSS字典 在签名时在签名中嵌入CRL或OCSP响应 DSS方法似乎是可行的,Adobe将签名识别为启用了LTV。第二种方法更适合我们的应用程序,所以我仍在努力让它工作。我在向签名添加OCSP响应时遇到了问题,所以我只尝试添加证书和CRL。如果我错了,请纠正我,但据我所知,CRL或OCSP响应都应该添加到签名中。不需要两者兼而有之吗?我收集签名证书及其根证书,还有TSA证书
在下面的代码中,我在方法签名中编写了throws,但在Lambda for write中,编译器给出了一个错误。为什么? 编译器错误:未处理的异常:java.io.IOException
我已经签署了一个应用程序与我创建的标志。我已经在我的手机里安装了这个apk,这是可以的,但是当我尝试打开应用程序时,它崩溃了(没有显示任何活动),并且它没有给我看日志的机会(这个对话框没有报告按钮) 问题是我在应用程序上的签名。我已经测试了其他标志和应用程序打开完美。我不能发布任何关于创建标志的信息,但只有我可以说我使用了: 其他字段为空。 主要的问题是这个应用程序是在google play中发布
输入是一个名为Wiki micro的文本文件。txt。。。字数计算程序运行正常。。我需要的是修改它 }
我正在尝试使用远程web服务来演唱pdf,该服务返回一个XML签名,该签名由签名和最终用户证书组成。 我需要使用此签名通过IText签名对pdf进行签名,因为web服务。 所有IText示例都使用消息格式,但我不确定应该如何处理XML签名。 打开临时Pdf并嵌入接收到的签名的代码 从web服务返回的XML签名: 当我将返回的签名与上面的代码一起使用时,签名验证失败,出现“错误遇到时BER解码”。