Abrir archivo pdf protegido con contraseña con iTextSharp

Estoy haciendo una aplicación que debe mostrar archivos PDF con contraseña. Este es mi código:

protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { try { string filePath = Request.QueryString["filePath"]; if (filePath.ToUpper().EndsWith("PDF")) { copyPDF(filePath); } } catch { string message = "alert('File Not Found! Call Records Department for verification. ')"; ScriptManager.RegisterStartupScript(Page, this.GetType(), message, message, false); } } } public void copyPDF(string filePath) { iTextSharp.text.pdf.RandomAccessFileOrArray ra = new iTextSharp.text.pdf.RandomAccessFileOrArray(Server.MapPath(ResolveUrl(filePath))); if (ra != null) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); byte[] password = System.Text.ASCIIEncoding.ASCII.GetBytes("Secretinfo"); iTextSharp.text.pdf.PdfReader thepdfReader = new iTextSharp.text.pdf.PdfReader(ra, password); int pages = thepdfReader.NumberOfPages; iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(); iTextSharp.text.pdf.PdfCopy pdfCopy = new iTextSharp.text.pdf.PdfCopy(pdfDoc, ms); pdfDoc.Open(); int i = 0; while (i < pages) { pdfCopy.AddPage(pdfCopy.GetImportedPage(thepdfReader, i + 1)); i += 1; } pdfDoc.Close(); Byte[] byteInfo = ms.ToArray(); Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-length", byteInfo.Length.ToString()); Response.BinaryWrite(byteInfo); Response.Flush(); Response.End(); } } 

Mi código no tiene problemas para abrir archivos PDF sin contraseña, pero no puede abrir archivos PDF con contraseña aunque se proporcione la contraseña. La aplicación ejecuta el catch en su lugar. ¿Qué parece estar mal con mi código?

EDITAR : eliminé la captura para ver la excepción lanzada.

Detalles de la excepción : System.ArgumentException: PdfReader no se abrió con la contraseña del propietario

Dice que la fuente del error es la Línea 51.

 Line 49: while (i < pages) Line 50: { Line 51: pdfCopy.AddPage(pdfCopy.GetImportedPage(thepdfReader, i + 1)); Line 52: i += 1; Line 53: } 

Para ciertas operaciones en documentos cifrados, iText (Sharp) requiere que el documento no se abra simplemente con la contraseña del usuario sino con la contraseña del propietario. Esto corresponde a la definición de estas contraseñas en la especificación PDF:

El que se permitan operaciones adicionales en un documento descifrado depende de la contraseña (si la hay) que se proporcionó cuando se abrió el documento y de las restricciones de acceso que se especificaron cuando se creó el documento:

  • Abrir el documento con la contraseña de propietario correcta debe permitir el acceso completo (propietario) al documento. Este acceso ilimitado incluye la capacidad de cambiar las contraseñas del documento y los permisos de acceso.
  • Abrir el documento con la contraseña de usuario correcta (o abrir un documento con la contraseña predeterminada) debe permitir realizar operaciones adicionales según los permisos de acceso de usuario especificados en el diccionario de cifrado del documento.

(sección 7.6.3.1 en ISO 32000-1 )

iText (Sharp) actualmente no verifica en detalle los permisos de acceso de usuario especificados en el diccionario de cifrado del documento, sino que siempre requiere la contraseña de propietario para las operaciones que requieren ciertos permisos, y la copia definitiva de páginas enteras de un documento es una de ellas.

Dicho esto, los desarrolladores de iText (Sharp) están muy conscientes (debido a muchas de esas preguntas)

  • que los usuarios de iText (Sharp) pueden tener derecho a ejecutar tales operaciones incluso sin la contraseña de propietario a cuenta de los permisos de acceso de usuario mencionados anteriormente en el diccionario de cifrado del documento,
  • que hay una miríada de archivos PDF a los que sus respectivos propietarios aplicaron una contraseña de propietario (para evitar su uso indebido por parte de terceros) y luego la olvidaron (o al usar una generada aleatoriamente que nunca la conocieron), y
  • que iText (Sharp) (siendo de código abierto) puede ser fácilmente parcheado por cualquiera que no respete las diferencias entre la contraseña del usuario y del propietario.

Para permitir a los usuarios hacer lo que les corresponde y para evitar la propagación de copias parcheadas de la biblioteca, iText (Sharp) contiene una anulación para esta prueba en la clase PdfReader :

 /** * The iText developers are not responsible if you decide to change the * value of this static parameter. * @since 5.0.2 */ public static bool unethicalreading = false; 

Por lo tanto, al establecer

 PdfReader.unethicalreading = true; 

Usted anula globalmente este mecanismo de verificación de permisos.

Respete los derechos de los autores de PDF y solo use esta anulación si tiene derecho a ejecutar las operaciones en cuestión.

Apliqué esta solución y funciona:

 private void fixIssue(PdfReader pdfReader) throws Exception { Field f = pdfReader.getClass().getDeclaredField("ownerPasswordUsed"); f.setAccessible(true); f.setBoolean(pdfReader, true); }