2014-10-09 13 views
7

Sto utilizzando iTextSharp 5.5.1 per firmare i file PDF in modo digitale con una firma separata (ottenuta da un'autorità di terze parti). Tutto sembra funzionare bene, il file è valido e ad es. Adobe Reader non segnala problemi, visualizza le firme come valide ecc.Rimuovi il segno di ordinazione byte dal file PDF firmato?

Il problema è che i client Java hanno apparentemente alcuni problemi con questi file - il file non può essere né aperto né analizzato.
I file hanno un segno di ordinamento dei byte nell'intestazione che sembra causare il comportamento (\ x00EF \ x00BB \ x00BF).

ho potuto identificare la distinta in questo modo:

PdfReader reader = new PdfReader(path); 
byte[] metadata = reader.Metadata; 
// metadata[0], metadata[1], metadata[2] contain the BOM 

Come posso rimuovere il BOM (senza perdere la validità della firma), o forzare la libreria iTextSharp di non accodare questi byte nei file?

+0

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

+0

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

+0

@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

risposta

6

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 ...

+0

* Seconda osservazione: il segno di ordine dei byte non fa parte dell'intestazione. È il valore dell'attributo begin * - è così che dovrebbe essere. Ma se ricordo male, il file firmato e crittografato dell'OP ha effettivamente ottenuto una BOM, vedere [qui] (http://i.stack.imgur.com/nrj3t.png). (In realtà volevo esaminarlo ma ho perso di vista il problema.) – mkl

+0

Intendo: non fa parte dell'intestazione PDF. L'intestazione del PDF ha il seguente aspetto: '% PDF-1.'. Chiarirò –

+0

Ho riletto la domanda. È ambiguo. Dice che il BOM fa parte dell'intestazione del * file *, ma l'esempio mostra che questo non è vero: la distinta base si trova nei metadati XMP. I metadati XMP sono racchiusi all'interno di uno stream all'interno di un file PDF. –

1

Solo un approccio rapido:

Primo: salvare entrambi i file non criptati. Secondo: rimuovere i metadati da 0 a 2 prima di salvare il file

Ci sono alcune considerazioni comunque: il metodo di firma richiede una DBA? Il metodo di crittografia richiede una BOM?

È inoltre necessario verificare in quale fase viene aggiunta la DBA prima di poter determinare se è possibile/deve rimuovere la DBA.

Avrò una rapida ricerca per i miei documenti di struttura pdf e vedere cosa posso ottenere, tuttavia il modo più semplice sarebbe (non sperimentato) caricare l'intera cosa come un array di byte e semplicemente rimuovere xEF xBB xBF dall'inizio del file , quindi fare qualsiasi firma/crittografia. Tuttavia essi possono aggiungerlo di nuovo ...

Io posto un aggiornamento durante il fine settimana :)