使用iText库在pdf中插入隐藏的摘要

我使用iText库(Java)搜索一个方法,用于将摘要(字节数组或字符串)插入PDF文件。 我使用此方法从String创建摘要:

private String crypt(double x, ByteArrayOutputStream baos) throws UnsupportedEncodingException, NoSuchAlgorithmException{ MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(String.valueOf(x).getBytes("UTF-8")); md.update(String.valueOf(baos).getBytes("UTF-8")); byte[] digest = md.digest(); StringBuffer sb = new StringBuffer(); for(byte d:digest){ sb.append(Integer.toHexString(0xFF & d)); } return sb.toString(); } 

摘要不应在PDF中看到,但必须将其摘录以进行比较。

此类私有数据可以存储在PieceInfo词典中:

页面字典(PDF 1.3)可用于保存私有的符合要求的产品数据。 数据可以通过页面对象中的可选PieceInfo条目(参见表30)或表单字典(参见表95)与页面或表单XObject相关联。 从PDF 1.4开始,私有数据也可以通过文档目录中的PieceInfo条目与PDF文档相关联(参见表28)。

( ISO 32000-1第14.5节)

在您的情况下,文档目录中的PieceInfo似乎最合适

使用iText,你可以在那里存储数据并使用下面的DocumentPieceInfo助手类再次检索它们:

存储文件PieceInfo数据

 PdfName appName = new PdfName("MYAPP"); PdfName dataName = new PdfName("Hash"); DocumentPieceInfo dpi = new DocumentPieceInfo(); PdfReader reader = new PdfReader(...); dpi.addPieceInfo(reader, appName, dataName, new PdfString(data)); PdfStamper stamper = new PdfStamper(reader, ...); stamper.close(); 

检索文档PieceInfo数据

 PdfName appName = new PdfName("MYAPP"); PdfName dataName = new PdfName("Hash"); DocumentPieceInfo dpi = new DocumentPieceInfo(); PdfReader reader = new PdfReader("target/test-outputs/test-with-piece-info.pdf"); PdfObject myData = dpi.getPieceInfo(reader, appName, dataName); 

DocumentPieceInfo助手类

 public class DocumentPieceInfo { static PdfName PIECE_INFO = new PdfName("PieceInfo"); static PdfName LAST_MODIFIED = new PdfName("LastModified"); static PdfName PRIVATE = new PdfName("Private"); void addPieceInfo(PdfReader reader, PdfName app, PdfName name, PdfObject value) { PdfDictionary catalog = reader.getCatalog(); PdfDictionary pieceInfo = catalog.getAsDict(PIECE_INFO); if (pieceInfo == null) { pieceInfo = new PdfDictionary(); catalog.put(PIECE_INFO, pieceInfo); } PdfDictionary appData = pieceInfo.getAsDict(app); if (appData == null) { appData = new PdfDictionary(); pieceInfo.put(app, appData); } PdfDictionary privateData = appData.getAsDict(PRIVATE); if (privateData == null) { privateData = new PdfDictionary(); appData.put(PRIVATE, privateData); } appData.put(LAST_MODIFIED, new PdfDate()); privateData.put(name, value); } PdfObject getPieceInfo(PdfReader reader, PdfName app, PdfName name) { PdfDictionary catalog = reader.getCatalog(); PdfDictionary pieceInfo = catalog.getAsDict(PIECE_INFO); if (pieceInfo == null) return null; PdfDictionary appData = pieceInfo.getAsDict(app); if (appData == null) return null; PdfDictionary privateData = appData.getAsDict(PRIVATE); if (privateData == null) return null; return privateData.get(name); } } 

此类假定Private值是一个字典,其中依次存储私有数据。 但它可能是任何东西。 要处理其他程序生成的私人数据,您可能需要一些变化。