有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在自定义签名中使用字体iText7的外观签名会破坏PDF/A一致性吗?

我试图从PDF/A-1A输入文件创建签名PDF,输出必须保持一致性级别

签名必须添加定制外观

如果我按照下面的代码行进行操作,那么签名端的一切都会正常工作,签名会正确显示并验证OK

但PDF/A一致性被不包含所需toUnicode CMAP的嵌入式字体打破

PdfADocument pdf = ... the doc to be signed
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfReader reader = pdf.getReader();
PrivateKey privateKey = ...
Provider signatureProvider = new BouncyCastleProvider();
Certificate[] signChain = ...
PdfSigner pdfSigner = new PdfSigner(reader, buffer, true);
PdfSignatureAppearance signatureAppearance = pdfSigner.getSignatureAppearance();
signatureAppearance.setReuseAppearance(false);
 signatureAppearance.setPageNumber(pdf.getNumberOfPages());
 pdfSigner.setFieldName("Custom Signature");
 float margin = 35;        
 Rectangle pageSize = pdf.getLastPage().getMediaBox();
 Rectangle signaturePosition = new Rectangle(pageSize.getLeft()+margin,
                                                pageSize.getBottom()+margin,
                                                pageSize.getWidth()-2*margin, 
                                                (pageSize.getHeight()-2*margin)/3);


    // need to do this before creating any *Canvas object, else the pageRect will be null and the signature invisible
    signatureAppearance.setPageRect(signaturePosition);

PdfFont regularFont = PdfFontFactory.createFont("/path/to/truetypefile-regular.ttf", "ISO-8859-1", true);
PdfFont boldFont = PdfFontFactory.createFont("/path/to/truetypefile-bold.ttf", "ISO-8859-1", true);

int fontSize = 10;

PdfFormXObject n0 = signatureAppearance.getLayer0();
PdfCanvas n0Canvas = new PdfCanvas(n0, pdfSigner.getDocument());
PdfFormXObject n2 = signatureAppearance.getLayer2();
Canvas n2Canvas = new Canvas(n2, pdfSigner.getDocument());
if(regularFont != null) {
    n2Canvas.setFont(regularFont);
    n0Canvas.setFontAndSize(regularFont, fontSize);
}
ImageData imageData = ImageDataFactory.create("/path/to/image.png");
Image image = new Image(imageData);
n2Canvas.add(image);

String layer2Text = ... some lines of text containing newlines and some simple markdown
String[] paragraphs = layer2text.split("\n\n");
for (String text : paragraphs) {
    boolean bold = false;
    if(text.startsWith("[bold]")) {
        bold = true;
        text = text.replaceFirst("^\\s*\\[bold\\]\\s*", "");
    }

    Paragraph p = new Paragraph(text);
    p.setFontSize(fontSize);
    if(bold) {
        p.setFont(boldFont);
    }
    n2Canvas.add(p);
}
...   pdfSigner.setCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);

PrivateKeySignature externalSignature = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA512, signatureProvider.getName());
BouncyCastleDigest externalDigest = new BouncyCastleDigest();

pdfSigner.signDetached(externalDigest, externalSignature, signChain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);

所以我想这里少了些什么。嵌入的字体不符合PDF/A,因为它们缺少ToUnicode CMAP键。 pdf工具验证程序的另一个错误是: “密钥编码的值是Difference,但必须是WinAnSienceCodeing或MacRomanEncoding。”这似乎是同样的问题

签名本身是可以看到的,样式和图像应该是合适的。只是字体看起来不太好


共 (0) 个答案