Per prima cosa: una volta che un file PDF è firmato, non è necessario modificare qualsiasi byte di questo PDF, perché tu invalidi la firma se lo fai.
Seconda osservazione: il byte di ordine è non parte dell'intestazione PDF (un PDF inizia sempre con %PDF-1.
). In questo contesto, è il valore dell'attributo begin
nell'istruzione di elaborazione dei metadati XMP. Non conosco nessun client Java che abbia un problema con quella sequenza di byte in un file. Se hanno un problema, c'è un problema con quel client, non con il file.
Byte Order Mark è un'indicazione della presenza di caratteri UTF-8. Nel contesto di XMP, abbiamo uno stream all'interno del PDF che contiene un file XML di testo chiaro che può essere utilizzato da un software che non è "PDF aware". Per esempio:
2 0 obj
<</Type/Metadata/Subtype/XML/Length 3492>>stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.1.0-jc003">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
dc:format="application/pdf"
pdf:Keywords="Metadata, iText, PDF"
pdf:Producer="iText® 5.5.4-SNAPSHOT ©2000-2014 iText Group NV (AGPL-version); modified using iText® 5.5.4-SNAPSHOT ©2000-2014 iText Group NV (AGPL-version)"
xmp:CreateDate="2014-11-07T16:36:55+01:00"
xmp:CreatorTool="My program using iText"
xmp:ModifyDate="2014-11-07T16:36:56+01:00"
xmp:MetadataDate="2014-11-07T16:36:56+01:00">
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">This example shows how to add metadata</rdf:li>
</rdf:Alt>
</dc:description>
<dc:creator>
<rdf:Seq>
<rdf:li>Bruno Lowagie</rdf:li>
</rdf:Seq>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>Metadata</rdf:li>
<rdf:li>iText</rdf:li>
<rdf:li>PDF</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default">Hello World example</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
endstream
Tale software non-PDF-aware cercherà la sequenza W5M0MpCehiHzreSzNTczkc9d
, che è una sequenza che è improbabile che appaiono per caso in un flusso di dati.
L'attributo begin
è lì per indicare che i caratteri nello stream utilizzano la codifica UTF-8. Sono lì perché è una buona pratica per loro essere lì, ma non sono obbligatori (ISO-16684-1).
Si potrebbe recuperare i metadati il modo di fare (byte[] metadata = reader.Metadata;
), rimuovere i byte, e cambiare il flusso con un'istanza PdfStamper
come questo:
stamper.XmpMetadata = metadata;
Dopo aver modificato i metadati, è possibile firmare il PDF.
Nota che un aspetto della tua domanda mi sorprende. Lei scrive:
// metadata[0], metadata[1], metadata[2] contain the BOM
E 'molto strano che i primi tre byte dei metadati XMP contengono la distinta. I metadati XMP suppongono di iniziare con <?xpacket
. In caso contrario, stai facendo la cosa giusta rimuovendo quei byte.
Avvertenza: un PDF può contenere metadati XMP a diversi livelli. In questo momento, stai esaminando il più comune: metadati a livello di documento. È possibile incontrare PDF con metadati XMP a livello di pagina, con XMP all'interno di un'immagine, ecc ...
Ho appena controllato e iTextSharp non aggiunge BOM da solo. Entrambi i PDF originali li avevano prima di firmare, o si aggiunge BOM ad un certo punto. – divanov
I metadati (che sono incorporati da qualche parte nel file PDF) hanno normalmente una distinta base e questo è ok. * Il problema è che i client Java hanno apparentemente qualche problema con quei file * - quali client Java? – mkl
@mkl: innanzitutto, InputStream legge l'array di byte, quindi XMLPullParse (android) genera XmlPullParserException dopo aver analizzato l'xml. L'utilizzo di BOMInputStream rimuove il BOM dalla String, quindi XMLPullParser può leggerlo in ogni caso. Ma il mio requisito è quello di avere il file originale senza il BOM. – lukasz