This tutorial contains examples that demonstrate the usage of DidiSoft OraPDFProtect (ORA_PDF_PROTECT) PL/SQL package. For some of the functions of the package you will need a X.509 certificate or a .pkcs12/.pfx (Personal Information Exchange) file with a private key and a certificate chain.
Table of contents
- Setup
- PDF usage restrictions and Owner Password
- Encrypt PDF with a password
- Encrypt PDF with a X.509 certificate
- Sign PDF
- Sign PDF with a visible signature
- Sign and encrypt PDF
- Sign and encrypt PDF with a visible signature
PDF usage restrictions and Owner Password
The PDF encryption capabilities provided by ORA_PDF_PROTECT are similar to those available in Oracle® Report Builder. When encrypting a PDF document, certain usage limitations can be specified. The usage rights limitations are defined as constants (using the same names as those in Report Builder):
ORA_PDF_PROTECT.ALL_PERMISSIONS | All permissions are granted |
ORA_PDF_PROTECT.NOCOPY | Prohibits copying or extracting content from the document |
ORA_PDF_PROTECT.NOASSEMBLY | Prohibits insert or delete pages |
ORA_PDF_PROTECT.NOFILLIN | Prohibits filling form fields or signature fields |
ORA_PDF_PROTECT.NOSCREENREADERS | Prohibits extracting text and graphics for accessibility support |
ORA_PDF_PROTECT.NOMODIFYANNOTATIONS | Prohibits adding or modifying text annotations and fill form fields |
ORA_PDF_PROTECT.NOMODIFYCONTENTS | Prohibits modifying the contents of the document |
ORA_PDF_PROTECT.NOPRINTING | Prohibits printing the PDF |
ORA_PDF_PROTECT.NOHIRESPRINTING | Allow printing only at a low resolution |
The usage rights are accompanied with an Owner Password – a special password that can be used later to modify the PDF usage restrictions.
Encrypt PDF with a password
A password protected PDF file uses a User Password (not to be mistaken with the Owner Password), and only those who know it can open the PDF document. The example below will demonstrate the overloaded versions of the ENCRYPT_PDF method where usage rights can also be specified for the output PDF file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | DECLARE -- input PDF BLOB read handle pdf_file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output encrypted PDF BLOB encrypted_pdf_blob BLOB; -- PDF permissions and password user_password VARCHAR2(200); owner_password VARCHAR2(200); pdf_permissions INTEGER; BEGIN DBMS_LOB.createtemporary(pdf_blob, TRUE); pdf_file_handle := BFILENAME('SSH_KEYS_DIR', '1.pdf'); -- directory name must be Upper case -- load the data into a BLOB DBMS_LOB.OPEN(pdf_file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( pdf_blob, pdf_file_handle, DBMS_LOB.GETLENGTH(pdf_file_handle) ); DBMS_LOB.CLOSE(pdf_file_handle); user_password := 'test123'; owner_password := 'my password'; pdf_permissions := ORA_PDF_PROTECT.NOCOPY + ORA_PDF_PROTECT.NOASSEMBLY + ORA_PDF_PROTECT.NOMODIFYCONTENTS; encrypted_pdf_blob := ORA_PDF_PROTECT.ENCRYPT_PDF(pdf_blob, user_password, owner_password, pdf_permissions); END; / |
Encrypt PDF with a X.509 certificate
Encrypting a PDF with a X.509 certificate is similar to encrypting with a password, but instead of a User Password a X.509 certificate is used. In order to open such encrypted PDF, the private key corresponding to the X.509 certificate will be needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | DECLARE -- file read handle file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output encrypted PDF BLOB encrypted_pdf_blob BLOB; -- X.509 certificate cert_blob BLOB; BEGIN pdf_blob := ... load PDF INTO a BLOB -- load X.509 certificate into a BLOB file_handle := BFILENAME('KEYS_DIR', 'DidiSoftEood.crt'); DBMS_LOB.createtemporary(cert_blob, TRUE); DBMS_LOB.OPEN(file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( cert_blob, file_handle, DBMS_LOB.GETLENGTH(file_handle) ); DBMS_LOB.CLOSE(file_handle); encrypted_pdf_blob := ORA_PDF_PROTECT.ENCRYPT_PDF(pdf_blob, cert_blob); END; / |
Sign PDF
A digital signature can be embedded inside a PDF file in order to prove who is the author of the document. Usually a digital signature is an encrypted message digest that is meaningful only for a computer program. The PDF document specification also supports digital signatures that have a visible signature appearance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | DECLARE -- file read handle file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output signed PDF BLOB signed_pdf_blob BLOB; -- PFX/p12 private key and chain storage pfx_blob BLOB; pfx_password VARCHAR2(200); BEGIN pdf_blob := ... load PDF INTO BLOB -- load .PFX (key storage) into a BLOB file_handle := BFILENAME('KEYS_DIR', 'didisoft.pkcs12.p12'); DBMS_LOB.createtemporary(pfx_blob, TRUE); DBMS_LOB.OPEN(file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( pfx_blob, file_handle, DBMS_LOB.GETLENGTH(file_handle) ); DBMS_LOB.CLOSE(file_handle); pfx_password := 'cobra34'; signed_pdf_blob := ORA_PDF_PROTECT.SIGN_PDF(pdf_blob, pfx_blob, pfx_password); END; / |
Sign PDF with a visible signature
A visual digital signature is a combination of a digital signature and visual appearance in the PDF document.
The appearance of a Visual signature in a PDF document is specified with a parameter of type ORA_PDF_VISUAL_SIGNATURE
ORA_PDF_VISUAL_SIGNATURE
1 2 3 4 5 6 7 8 9 10 | ORA_PDF_VISUAL_SIGNATURE AS object ( Signature_Text VARCHAR2(200), -- signature text Rectangle_X1 INTEGER, -- signature rectangle lower left corner X coordinate Rectangle_Y1 INTEGER, -- signature rectangle lower left corner Y coordinate Rectangle_X2 INTEGER, -- signature rectangle upper right corner X coordinate Rectangle_Y2 INTEGER, -- signature rectangle upper right corner Y coordinate Page_No INTEGER, -- page where the visible signature will appear BG_Image BLOB, -- optional background image loaded from GIF, PNG, JPG Text_Color VARCHAR(20) -- optional, default is 'black' ); |
An instance of ORA_PDF_VISUAL_SIGNATURE with default values can be initialized with:
1 | visual_options := ORA_PDF_PROTECT.EMPTY_VISUAL_SIGNATURE; |
Signature text (property Signature_Text)
The text displayed in the visual signature is specified with the Signature_Text property. Special variables can be used in this text :
${signer} – the name of the certificate owner extracted from the .pfx file used for signing.
${timestamp} – this will be substituted with the date and time of the operation
New line can be added to the signature text with the CHR(13) character.
visual_options.Signature_Text := 'Signed by ${signer}';
Signature rectangle (properties Rectangle_X1, Rectangle_Y1, Rectangle_X2, Rectangle_Y2)
The signature rectangle is the box containing the visual signature. A PDF page uses a coordinate system starting in the bottom left corner (point [1,1]) and ending at the upper right cornet point (X=612, Y=792). The image below illustrates how to place a 200 points wide and 100 points tall signature rectangle in three different positions – lower left angle, center of a page, upper right angle:
Signature page (property Page_No):
The signature page is specified with the Page_No property. If the specified page number is bigger than the number of pages in the PDF document, it will be set for the last page.
A special value is available ORA_PDF_PROTECT.SIGNATURE_ON_ALL_PAGES which if used for Page_No will make the visible signature appear on all pages of the PDF document!
visual_options.Page_No := 1; visual_options.Page_No :=ORA_PDF_PROTECT.SIGNATURE_ON_ALL_PAGES
Background image (property Background_Image)
The background image can be loaded from a GIF, PNG or JPG image. If specified the image will be scaled to fill the signature rectangle.
Text color (property Text_Color)
The default text color in the visible signature rectangle is black. Often when a background image is specified, the text color shall also be changed in order to be more readable. A set of predefined text colors are available: black, blue, cyan, darkgray, gray, green, yellow, lightgray, magenta, orange, pink, red, white.
The color can also be specified as RGB color value like ‘#336699’ or ‘336699’
visual_options.Text_Color := 'yellow'; visual_options.Text_Color := '#336699';
Example with a visible signature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | DECLARE -- file read handle file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output signed PDF BLOB signed_pdf_blob BLOB; -- PFX/p12 private key and chain storage pfx_blob BLOB; pfx_password VARCHAR2(200); -- visual signature appearance options ORA_PDF_VISUAL_SIGNATURE; BEGIN -- load PDF into a BLOB pdf_blob := ... load PDF INTO BLOB field -- load .PFX (key storage) into a BLOB file_handle := BFILENAME('KEYS_DIR', 'didisoft.pkcs12.p12'); DBMS_LOB.createtemporary(pfx_blob, TRUE); DBMS_LOB.OPEN(file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( pfx_blob, file_handle, DBMS_LOB.GETLENGTH(file_handle) ); DBMS_LOB.CLOSE(file_handle); pfx_password := 'cobra34'; -- Visual signature options options := ORA_PDF_PROTECT.EMPTY_VISUAL_SIGNATURE; options.Signature_Text := 'Digitally signed by ${signer}' || CHR(13) || 'Date: ${timestamp}'; options.Rectangle_X1 := 1; options.Rectangle_Y1 := 1; options.Rectangle_X2 := 150; options.Rectangle_Y2 := 100; options.Page_No := ORA_PDF_PROTECT.SIGNATURE_ON_ALL_PAGES; -- options.Background_Image := ... BLOB loaded from GIF,JPG or PNG image options.Text_Color := 'blue'; signed_pdf_blob := ORA_PDF_PROTECT.SIGN_PDF_VISUAL(pdf_blob, pfx_blob, pfx_password, options); END; / |
Sign and encrypt PDF
The SIGN_AND_ENCRYPT_PDF method of the ORA_PDF_PROTECT package combines the encrypting and signing process in one step. The set of parameters is the same as in those operations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | DECLARE -- file read handle file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output signed PDF BLOB signed_pdf_blob BLOB; -- PFX/p12 private key and chain storage pfx_blob BLOB; pfx_password VARCHAR2(200); -- PDF permissions and password user_password VARCHAR2(200); owner_password VARCHAR2(200); pdf_permissions INTEGER; BEGIN DBMS_Java.set_output(10000); pdf_blob := ...-- load PDF into a BLOB -- load .PFX (key storage) into a BLOB file_handle := BFILENAME('KEYS_DIR', 'didisoft.pkcs12.p12'); DBMS_LOB.createtemporary(pfx_blob, TRUE); DBMS_LOB.OPEN(file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( pfx_blob, file_handle, DBMS_LOB.GETLENGTH(file_handle) ); DBMS_LOB.CLOSE(file_handle); pfx_password := 'cobra34'; user_password := 'test123'; owner_password := 'my password'; -- Restrict all permissions pdf_permissions := ORA_PDF_PROTECT.NOCOPY + ORA_PDF_PROTECT.NOASSEMBLY + ORA_PDF_PROTECT.NOFILLIN + ORA_PDF_PROTECT.NOSCREENREADERS + ORA_PDF_PROTECT.NOMODIFYANNOTATIONS + ORA_PDF_PROTECT.NOMODIFYCONTENTS + ORA_PDF_PROTECT.NOPRINTING; signed_pdf_blob := ORA_PDF_PROTECT.SIGN_AND_ENCRYPT_PDF(pdf_blob, pfx_blob, pfx_password, user_password, owner_password, pdf_permissions); END; / |
Sign and encrypt PDF with a visible signature
The ORA_PDF_PROTECT.SIGN_AND_ENCRYPT_PDF_VISUAL method also combines the visual signing and encrypting in a single step. The appearance of the Visual signature is customized through the ORA_PDF_VISUAL_SIGNATURE object.
Sign and encrypt PDF
The SIGN_AND_ENCRYPT_PDF method of the ORA_PDF_PROTECT package combines the encrypting and signing process in a single step. The set of parameters is the same as in those operations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | DECLARE -- file read handle file_handle BFILE; -- input PDF BLOB pdf_blob BLOB; -- output signed PDF BLOB signed_pdf_blob BLOB; -- PFX/p12 private key and chain storage pfx_blob BLOB; pfx_password VARCHAR2(200); -- visual signature appearance options ORA_PDF_VISUAL_SIGNATURE; -- PDF permissions and password user_password VARCHAR2(200); owner_password VARCHAR2(200); pdf_permissions INTEGER; BEGIN pdf_blob := ... -- load PDF into a BLOB -- load .PFX (key storage) into a BLOB file_handle := BFILENAME('KEYS_DIR', 'didisoft.pkcs12.p12'); DBMS_LOB.createtemporary(pfx_blob, TRUE); DBMS_LOB.OPEN(file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( pfx_blob, file_handle, DBMS_LOB.GETLENGTH(file_handle) ); DBMS_LOB.CLOSE(file_handle); pfx_password := 'cobra34'; -- Visual signature options options := ORA_PDF_PROTECT.EMPTY_VISUAL_SIGNATURE; options.Signature_Text := 'Digitally signed by ${signer}' || CHR(13) || 'Date: ${timestamp}'; options.Rectangle_X1 := 1; options.Rectangle_Y1 := 1; options.Rectangle_X2 := 150; options.Rectangle_Y2 := 100; options.Page_No := ORA_PDF_PROTECT.SIGNATURE_ON_ALL_PAGES; -- options.Background_Image := ... BLOB loaded with GIF,JPG or PNG image user_password := 'test123'; owner_password := 'my password'; -- Restrict all permissions pdf_permissions := ORA_PDF_PROTECT.NOCOPY + ORA_PDF_PROTECT.NOASSEMBLY + ORA_PDF_PROTECT.NOFILLIN + ORA_PDF_PROTECT.NOSCREENREADERS + ORA_PDF_PROTECT.NOMODIFYANNOTATIONS + ORA_PDF_PROTECT.NOMODIFYCONTENTS + ORA_PDF_PROTECT.NOPRINTING; signed_pdf_blob := ORA_PDF_PROTECT.SIGN_AND_ENCRYPT_PDF_VISUAL(pdf_blob, pfx_blob, pfx_password, options, user_password, owner_password, pdf_permissions); |
Summary
This article is a starting point for using DidiSoft OraPDFProtect. Complete PL/SQL examples can be found in the \Examples folder that ships inside the product ZIP file.