- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当使用 itext v5.5.11 对文档进行数字签名时,PDF/A-2b 文档会损坏 - 这意味着它们不再有效作为 PDF/A 文档。违反了以下规则: https://github.com/veraPDF/veraPDF-validation-profiles/wiki/PDFA-Parts-2-and-3-rules#rule-643-1
在上面的链接中指定了摘要无效,因此我还为您提供了一个代码段,该代码段在使用 iText 签署 pdf 文档时处理计算摘要:
// Make the digest
InputStream data;
try {
data = signatureAppearance.getRangeStream();
} catch (IOException e) {
String message = "MessageDigest error for signature input, type: IOException";
signLogger.logError(message, e);
throw new CustomException(message, e);
}
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException ex) {
String message = "MessageDigest error for signature input, type: NoSuchAlgorithmException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}
byte[] buf = new byte[8192];
int n;
try {
while ((n = data.read(buf)) > 0) {
messageDigest.update(buf, 0, n);
}
} catch (IOException ex) {
String message = "MessageDigest update error for signature input, type: IOException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}
byte[] hash = messageDigest.digest();
// If we add a time stamp:
// Create the signature
PdfPKCS7 sgn;
try {
sgn = new PdfPKCS7(key, chain, configuration.getSignCertificate().getSignatureHashAlgorithm().value() , null, new BouncyCastleDigest(), false);
} catch (InvalidKeyException ex) {
String message = "Certificate PDF sign error for signature input, type: InvalidKeyException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
} catch (NoSuchProviderException ex) {
String message = "Certificate PDF sign error for signature input, type: NoSuchProviderException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
} catch (NoSuchAlgorithmException ex) {
String message = "Certificate PDF sign error for signature input, type: NoSuchAlgorithmException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}catch (Exception ex) {
String message = "Certificate PDF sign error for signature input, type: Exception";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null,null, MakeSignature.CryptoStandard.CMS);
try {
sgn.update(sh, 0, sh.length);
} catch (java.security.SignatureException ex) {
String message = "Certificate PDF sign error for signature input, type: SignatureException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}
byte[] encodedSig = sgn.getEncodedPKCS7(hash);
if (contentEstimated + 2 < encodedSig.length) {
String message = "The estimated size for the signature is smaller than the required one. Terminating request..";
signLogger.log("ERROR", message);
throw new CustomException(message);
}
byte[] paddedSig = new byte[contentEstimated];
System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
// Replace the contents
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
try {
signatureAppearance.close(dic2);
} catch (IOException ex) {
String message = "PdfSignatureAppearance close error for signature input, type: IOException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
} catch (DocumentException ex) {
String message = "PdfSignatureAppearance close error for signature input, type: DocumentException";
signLogger.logError(message, ex);
throw new CustomException(message, ex);
}
对于 PDF/A 验证,我使用 VeraPDF 库。
提及 VeraPDF 库报告损坏的 PDF/A 库时,Adobe Reader 验证工具报告 PDF/A 文档未损坏可能也有帮助。
任何帮助将不胜感激。
最佳答案
When digitally signing document with itext v5.5.11 PDF/A-2b documents get corrupted - meaning they are no longer valid as PDF/A documents. Following rule is violated: https://github.com/veraPDF/veraPDF-validation-profiles/wiki/PDFA-Parts-2-and-3-rules#rule-643-1
虽然这确实是 veraPDF 所声称的,但这是错误的; iText 创建的签名覆盖整个修订版减去为签名容器保留的空间。
这种不正确的违规检测的原因是 veraPDF 中的错误。
veryPDF 版本(基于 greenfield 解析器的版本和基于 PDFBox 的版本)都试图确定标称字节范围值并将其与实际值进行比较。这就是它确定标称值的方式:
public long[] getByteRangeBySignatureOffset(long signatureOffset) throws IOException {
pdfSource.seek(signatureOffset);
skipID();
byteRange[0] = 0;
parseDictionary();
byteRange[3] = getOffsetOfNextEOF(byteRange[2]) - byteRange[2];
return byteRange;
}
private long getOffsetOfNextEOF(long currentOffset) throws IOException {
byte[] buffer = new byte[EOF_STRING.length];
pdfSource.seek(currentOffset + document.getHeaderOffset());
readWholeBuffer(pdfSource, buffer);
pdfSource.rewind(buffer.length - 1);
while (!Arrays.equals(buffer, EOF_STRING)) { //TODO: does it need to be optimized?
readWholeBuffer(pdfSource, buffer);
if (pdfSource.isEOF()) {
pdfSource.seek(currentOffset + document.getHeaderOffset());
return pdfSource.length();
}
pdfSource.rewind(buffer.length - 1);
}
long result = pdfSource.getPosition() + buffer.length - 1; // offset of byte after 'F'
pdfSource.seek(currentOffset + document.getHeaderOffset());
return result - 1;
}
(基于 PDFBox 的 SignatureParser
类)
public long[] getByteRangeBySignatureOffset(long signatureOffset) throws IOException {
source.seek(signatureOffset);
skipID();
byteRange[0] = 0;
parseDictionary();
byteRange[3] = getOffsetOfNextEOF(byteRange[2]) - byteRange[2];
return byteRange;
}
private long getOffsetOfNextEOF(long currentOffset) throws IOException {
byte[] buffer = new byte[EOF_STRING.length];
source.seek(currentOffset + document.getHeader().getHeaderOffset());
source.read(buffer);
source.unread(buffer.length - 1);
while (!Arrays.equals(buffer, EOF_STRING)) { //TODO: does it need to be optimized?
source.read(buffer);
if (source.isEOF()) {
source.seek(currentOffset + document.getHeader().getHeaderOffset());
return source.getStreamLength();
}
source.unread(buffer.length - 1);
}
long result = source.getOffset() - 1 + buffer.length; // byte right after 'F'
source.seek(currentOffset + document.getHeader().getHeaderOffset());
return result - 1;
}
(基于SignatureParser
的绿地解析器)
本质上,这两种实现在这里都做同样的事情,从签名开始,它们寻找文件结束标记 %%EOF
的下一次出现,并尝试完成标称字节范围值,以便第二个范围以该标记结束。
这种确定标称带符号字节范围值的方法错误的原因有多种:
根据PDF/A规范,
No data can follow the last end-of-file marker except a single optional end-of-line marker as described in ISO 32000-1:2008, 7.5.5.
因此,紧接在下一个文件结束标记 %%EOF
之后的偏移量不一定已经是签名修订的结尾,正确的偏移量可能是下一个行尾标记之后的那个!由于 PDF 行尾标记可以是单个 CR 或单个 LF 或 CRLF 组合,这意味着 veraPDF 选择三个可能的偏移量之一,并声称它是修订的名义结束因此,有符号字节范围的标称结束。
有可能(即使几乎从未见过)在一次修订中准备签名值(以文件结束标记结尾),然后在增量更新中附加一些数据,从而产生新修订(以另一个文件结束标记结束),然后签名值填充为签署文档的值,包括这个新修订。
由于 veraPDF 在签名字典之后使用下一个文件结束标记,在这种情况下 veraPDF 实际上选择了错误的文件结束标记。。 p>
文件结束标记 %%EOF
在句法上实际上只是一个在 PDF/修订版末尾具有特殊含义的注释,并且几乎在任何地方都允许注释PDF 外部 PDF 字符串、PDF 流数据和 PDF 交叉引用表。因此,字节序列 %%EOF
可以作为常规注释或字符串的非注释内容或流在签名值字典和已签名修订的实际结尾之间出现任意次数.
如果出现这种情况,veraPDF 会选择一个字节序列作为文件结束标记,该标记永远不会作为某事的结束。
此外,除非在循环中到达实际的文件结尾(并且返回 pdfSource.length()
/source.getStreamLength()
),否则结果出现差一,return result - 1
中的- 1
与result的使用不对应。
我检查了标记为 veraPDF 的当前 1.5.0-SNAPSHOT 版本:
OP 提供的示例文档在文件结束标记后有一个 LF。由于这个和上面提到的差一问题,veraPDF 确定了一个标称有符号字节范围结束,这是两个字节短。
关于java - iText 数字签名损坏 PDF/A 2b,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43522415/
我得到了这个printHashKey函数,它运行良好。 fun printHashKey() { try { val info : PackageInfo = packageM
如何使用正确的签名 key 为我的 Android 应用包签名? 最佳答案 我尝试在此处和 this question 中使用多个答案, 但不知何故我收到了这个错误,因为我的 android/app/
我的 gradle 文件中有这个: android { signingConfigs { mySigningConfig { keyAlias 'the
请至少选择一个签名版本以在 Android Studio 2.3 中使用 现在在 Android Studio 中生成一个签名的 APK 时,它显示了两个选项(复选框),即 1. V1(Jar 签名)
我想表示一些标量值(例如整数或字符串)通过它的实际值或一些 NA 值,然后存储它们在集合中(例如列表)。目的是处理缺失值。 为此,我实现了一个签名 module type Scalar = sig
为什么这不完全有效? sum :: (Num a, Num b) => a -> b -> c sum a b = a + b 当然,错误消息与签名有关,但我仍然不明白原因。 Couldn't mat
谢谢帮助,我的问题是关于从下面的代码中收到的 ax 值? mov al,22h mov cl,0fdh imul cl 真机结果:ff9a 我的预期:00:9a(通过二进制相乘) 第一个数字是 22h
我有一个注释: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.
我从对物体的思考中得出了一个术语。当我们扩展一个类时,扩展类将具有与父类相同的签名,因此术语 IS-A 来自...示例 class Foo{ } class Foo2 extends Foo{ } c
我需要在有符号整数和它们作为字节序列的内部表示之间进行转换。在 C 中,我使用的函数如下: unsigned char hibyte(unsigned short i) {return i>>8;}
我正在尝试使用给定的 RSA 参数对一些数据进行签名。 我给出了模数、指数、D、DP、DQ、P、Q 和 InverseQ。什么库或方法最容易使用来计算此签名。在 C# 中,一旦您提供参数,它们就会有一
这些签名之间有什么区别? T * f(T & identifier); T & f(T & identifier); T f(T & identifier); void f(T * identifie
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Where and why do I have to put the “template” and “typ
我有一个签名,我需要在签名旁边添加图片。但我不确定 css 的确切程度和内容。目前它显示在文字下方,我应该把图片放在哪里?在相同的 tr 或 td 中?
查看 LinkedHashMap 的 JDK 源代码,我注意到这个类被声明为: public class LinkedHashMap extends HashMap im
背景:我继承了一个基于 linux 的嵌入式系统,其中包含一个 SMTP 代理和一些我不得不忍受的古怪限制。它位于 SMTP 客户端和服务器之间。当 SMTP 客户端连接时,代理会打开与服务器的连接,
这是 C++17 形式的规则 ([basic.lval]/8),但它在其他标准中看起来很相似(在 C++98 中是“lvalue”而不是“glvalue”): 8 If a program attem
我有一个注释: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.
我即将开展一个项目,希望使用电子签名板使用 C# 捕获客户的签名、在设备上显示文本等。 现在,在我开始做进一步的研究之前,我想向你们征求一些意见/建议,我应该使用哪些设备.. 我现在的要求非常笼统:我
呢喃自己在心中开始扩张地盘,仿佛制式地广播了三次。 漾起的涟绮,用谈不上精腻的手段。 拒绝天亮,却又贪恋着贪恋多情的日光。 川流不息的画面是他们,而我的落幕停在右脚,它渴望着下台,而我只剩自言
我是一名优秀的程序员,十分优秀!