android - 如何从摘要生成 PKCS#7 签名?

标签 android digital-signature bouncycastle pdfbox pkcs#7

我想使用 pdf 摘要签署 pdf。我使用以下代码创建了哈希,

byte[] buffer = new byte[1024];
int numOfBytesRead =0;
MessageDigest md = null;
md = MessageDigest.getInstance("SHA256","BC");
while((numOfBytesRead = content.read(buffer)) != -1 ){
     md.update(buffer, 0, numOfBytesRead);
}
byte[] digest = md.digest();

最后,我需要将此签名附加到我的 pdf 中。我找到了一种解决方案 Create pkcs7 signature from file digest ,但链接中使用的算法是 SHA256withRSA。我的私钥是使用 EC 算法生成的,我需要使用 SHA256withECDSA。是否可以只使用 SHA256withECDSA 对哈希进行签名并将签名附加到使用 PDFBox ExternalSigning 接口(interface)的 pdf。

最佳答案

有几种情况 Adob​​e 会称签名者的证书无效,即使它表面上是有效的;特别是在手头的情况下:

  • key 使用或扩展 key 使用值不合适
  • PAdES 签名缺少 ESS signing-certificate-v2 属性

key 使用或扩展 key 使用值不合适

这是基于 OP 首次发布为 an answer 的信息

I tried below code still the pdf says Signature is invalid. Can you please check the code,

[...]

I have attached the pdf . Pdf file created

确实,Adobe Reader 说签名无效,但仔细观察:

Signature panel

它说“文档自应用此签名以来未被修改”- 这意味着签名在数学上是正确的!

问题是“Signer's certificate is invalid”,在深入研究签名属性对话框时可以看出其原因:

Certificate Details

因此,问题是您的签署者证书无效

这是由于突出显示的属性,而 key 使用数字签名没问题,“扩展 key 使用”1.3.6.1.5.5.8.2.2 ( IPSEC 保护的 OID)不是!

根据 Adob​​e Digital Signatures Guide for IT , Adob​​e Acrobat 只接受

  • 以下一个或多个 key 使用值(如果有)

    • 不可否认
    • signTransaction(仅限 11.0.09)
    • digitalSignature(11.0.10 及更高版本)
  • 以及以下一个或多个扩展 key 使用值(如果有)

    • 邮件保护
    • 代码签名
    • 任何扩展 key 使用
    • 1.2.840.113583.1.1.5(Adobe 真实文档信任)

由于其IPSEC 保护 扩展 key 使用值,因此,您的证书被视为对签署 PDF 文档无效。

这可能只是遗留 ISO 32000-1 签名中的问题,可能不是 PAdES 签名中的问题。

PAdES 签名缺少 ESS signing-certificate-v2 属性

这是基于 OP 首次发布为 an answer 的信息

I have created 2 pdf files, PDFA is signed using the digest of the pdf content with below code,

[...]

PDFA

PDFB is created with the same private key and certificate, but instead of digest I am using pdf document content directly which gives me valid signed pdf, PDFB code below,

[...]

PDFB

I think something is missing in the signing part of PDFA which I couldn't figure out.

这里的主要区别不是您自己显式计算散列还是允许隐式计算,主要区别在于 PDFB 中的签名包含 ESS signing-certificate-v2 属性,而 PDFA 中没有。该属性产生于

//PAdES - PDF Advanced Electronic Signature

//PAdES-end

正如评论已经暗示的那样,这只是 PAdES 签名所必需的,而不是旧版 ISO 32000-1 签名所必需的。 The answer the OP took his original code from提到在 OP 创建 PAdES 签名时创建旧版 ISO 32000-1 签名(因此可以正常工作)。

PAdES 规范 ETSI EN 319 142-1 要求存在 ESS 签名证书属性:

e) Generators shall use either the signing certificate or the signing-certificate v2 attribute, depending on the hash function, in accordance with ETSI EN 319 122-1.

(ETSI EN 319 142-1,第 6.3 节 PAdES 基线签名)

它引用了 CAdES 规范 ETSI EN 319 122-1,后者又要求

h) Requirement for SPO: ESS signing-certificate. The ESS signing-certificate attribute shall be used if the SHA-1 hash algorithm is used.

i) Requirement for SPO: ESS signing-certificate-v2. The ESS signing-certificate-v2 attribute shall be used when another hash algorithms than SHA-1 is used.

(ETSI EN 319 122-1,第 6.3 节组件和服务要求)

关于android - 如何从摘要生成 PKCS#7 签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52757037/

相关文章:

java - 需要帮助了解证书链

android - 从 Android Market 安装应用后获取推荐人

android - 传递自定义对象的数组列表以从 android 响应 native 端

Android fragment 找不到 id 的 View

java - 使用 bouncyCaSTLe.SecurityException 打包在独特的 jar 中

ssl - TLS 1.2 ECDHE_RSA 签名

java - 无法从 .pem 文件读取 DSA key

java - 在 Android 中使用显式 Intent 进行文本比较

c# - BouncyCaSTLe,生成RSA key 对需要多长时间?

c# - 是否可以仅使用 C# 以编程方式生成 X509 证书?