【问题标题】:Apache PDFBox 2.0.4 how to validate pdf with subfilter "adbe.x509.rsa_sha1".?Apache PDFBox 2.0.4 如何使用子过滤器“adbe.x509.rsa_sha1”验证 pdf。?
【发布时间】:2017-04-13 05:01:10
【问题描述】:

因为我可以从附加在内容部分的证书中获取证书对象..我对如何验证/验证 PKCS#1 即 adbe.x509.rsa_sha1 的签名内容感到困惑。任何帮助将不胜感激。!!

【问题讨论】:

  • 另一个问题:过去几年基于 PKCS#7 / CMS 的集成 PDF 签名方案被证明是首选(IMO 有充分的理由),但最近一些关于基于 PKCS#1 的方案的问题开始流行向上。是否有一些新的上下文更适合后者?
  • 说了这么多,你对安全知识了解多少?你知道吗?用 bouncycastle 怎么玩?
  • 实际上对于我的应用程序,我正在使用所有类型的 pdf 文档进行测试,我遇到了带有此子过滤器的 pdf 等问题。对于 bouncycastle 来说不多,但可以。
  • 好的。你能分享那个示例文件吗?你需要什么样的验证?您是否只想验证签名是否与签名数据匹配?还是您还想检查相关证书的有效性?

标签: java pdf digital-signature pdfbox pkcs#1


【解决方案1】:
COSDictionary sigDict = sig.getCOSObject();
COSString contents = (COSString) sigDict.getDictionaryObject(COSName.CONTENTS);
// download the signed content
byte[] buf;
try (FileInputStream fis = new FileInputStream(infile))
{
    buf = sig.getSignedContent(fis);
}
COSString certString = (COSString) sigDict.getDictionaryObject(COSName.CERT);
byte[] certData = certString.getBytes();
CertificateFactory factory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
Collection<? extends Certificate> certs = factory.generateCertificates(certStream);

// inspired by:
// https://www.programcreek.com/java-api-examples/index.php?source_dir=pades_signing_2.1.5-master/src/main/java/com/opentrust/spi/pdf/PDFEnvelopedSignature.java
ASN1InputStream asn1IS = new ASN1InputStream(new ByteArrayInputStream(contents.getBytes()));
ASN1Primitive asn1prim = asn1IS.readObject();
if (!(asn1prim instanceof ASN1OctetString))
{
    throw new IOException("ASN1 octet string expected, but got " + asn1prim.getClass().getSimpleName());
}
ASN1OctetString oct = (ASN1OctetString) asn1prim;
X509Certificate cert = (X509Certificate) certs.iterator().next();
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(cert.getPublicKey());
signature.update(buf);
System.out.println("Verification result: " + signature.verify(oct.getOctets()));

上半部分取自 PDFBox 的 ShowSignature.java 示例。下面的部分基于 Paulo Soares 的 OpenTrust/pades_signing_2.1.5 中的 PDFEnvelopedSignature 类中的代码,请参阅源代码中的许可证herehere

可以在问题 PDFBOX-2693 中找到示例文件。

2018 年 11 月 30 日更新:

使用cert.getSigAlgName() 获取算法并不总是给出实际算法。上面的链接还显示了获取正确摘要算法的代码,在“oct =”行之后插入以下代码:

Cipher c = Cipher.getInstance("RSA/NONE/PKCS1Padding", SecurityProvider.getProvider());
c.init(Cipher.DECRYPT_MODE, cert.getPublicKey());
byte[] raw = c.doFinal(oct.getOctets());
DigestInfo di = DigestInfo.getInstance(raw);
String algID = di.getAlgorithmId().getAlgorithm().getId();

有效值为:

RIPEMD160  1.3.36.3.2.1            TeleTrusTObjectIdentifiers.ripemd160
SHA1       1.3.14.3.2.26           OIWObjectIdentifiers.idSHA1
SHA256     2.16.840.1.101.3.4.2.1  NISTObjectIdentifiers.id_sha256
SHA384     2.16.840.1.101.3.4.2.2  NISTObjectIdentifiers.id_sha384
SHA512     2.16.840.1.101.3.4.2.3  NISTObjectIdentifiers.id_sha512

但是,除了 SHA1 之外,我从来没有其他任何东西,这就是我现在对其进行硬编码的原因。

【讨论】:

  • 我对@9​​87654328@ 有点惊讶 - 尽管子过滤器名称 adbe.x509.rsa_sha1 散列算法不必是 SHA1。
  • 你是对的......虽然 PDF 规范曾经在一个表格中提到了几个并告诉“尽管在这个 SubFilter 值的名称中出现了 sha1,但支持的编码不应限于 SHA1 算法。 PKCS#1 对象包含一个标识符,指示应使用哪种算法”,在另一个地方它告诉“应使用的 SubFilter 的唯一值是 adbe.x509.rsa_sha1,它使用 RSA 加密算法和 SHA-1 摘要方法”。
猜你喜欢
  • 2013-08-28
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多