DataFlex Requires Chilkat v11.7.0+
DataFlex
Encrypt and Sign a PDF, and Sign an Encrypted PDF
See more PDF Protection Examples
Demonstrates signing together with encryption. A pending encrypt is applied by SignPdf before it signs, so one call produces a PDF that is both encrypted and signed. A PDF that is already encrypted can be signed too, and stays encrypted. When it was opened with only the user password its permissions decide: adding a signature field needs both the modify and the annotate permission. Loading the PDF with its owner password lifts that.Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Variant vCert
Handle hoCert
Handle hoPdf
Variant vJson
Handle hoJson
Variant vJsonOut
Handle hoJsonOut
Variant vSigOpts
Handle hoSigOpts
Handle hoCheck
Variant vEmpty
Handle hoEmpty
Variant vInfo
Handle hoInfo
Variant vSigInfo
Handle hoSigInfo
Boolean iVerified
Handle hoOwner
Handle hoTwice
String sTemp1
Integer iTemp1
Move False To iSuccess
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
// The PDF used in this example is available at two_page_memo.pdf
// The signing certificate, with its private key.
Get Create (RefClass(cComChilkatCert)) To hoCert
If (Not(IsComObjectCreated(hoCert))) Begin
Send CreateComObject of hoCert
End
Get ComLoadPfxFile Of hoCert "qa_data/pfx/myPdfSigningCert.pfx" "secret" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCert To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatPdf)) To hoPdf
If (Not(IsComObjectCreated(hoPdf))) Begin
Send CreateComObject of hoPdf
End
Get ComLoadFile Of hoPdf "qa_data/pdf/two_page_memo.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPdf To sTemp1
Showln sTemp1
Procedure_Return
End
// Encrypt with AES-256 and do not permit modifying.
Set ComUserPassword Of hoPdf To "user-secret"
Set ComOwnerPassword Of hoPdf To "owner-secret"
Get Create (RefClass(cComChilkatJsonObject)) To hoJson
If (Not(IsComObjectCreated(hoJson))) Begin
Send CreateComObject of hoJson
End
Get ComUpdateBool Of hoJson "permissions.modify" False To iSuccess
Get Create (RefClass(cComChilkatJsonObject)) To hoJsonOut
If (Not(IsComObjectCreated(hoJsonOut))) Begin
Send CreateComObject of hoJsonOut
End
Get pvComObject of hoJson to vJson
Get pvComObject of hoJsonOut to vJsonOut
Get ComProtection Of hoPdf "encrypt" vJson vJsonOut To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPdf To sTemp1
Showln sTemp1
Procedure_Return
End
// The encryption is still pending. SignPdf applies it first and signs the encrypted result.
Get pvComObject of hoCert to vCert
Get ComSetSigningCert Of hoPdf vCert To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPdf To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatJsonObject)) To hoSigOpts
If (Not(IsComObjectCreated(hoSigOpts))) Begin
Send CreateComObject of hoSigOpts
End
Get ComUpdateBool Of hoSigOpts "invisibleSignature" True To iSuccess
Get ComUpdateInt Of hoSigOpts "signingCertificateV2" 1 To iSuccess
Get ComUpdateInt Of hoSigOpts "signingTime" 1 To iSuccess
Get pvComObject of hoSigOpts to vSigOpts
Get ComSignPdf Of hoPdf vSigOpts "qa_output/memo_encrypted_signed.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPdf To sTemp1
Showln sTemp1
Procedure_Return
End
// The result is encrypted and signed.
Get Create (RefClass(cComChilkatPdf)) To hoCheck
If (Not(IsComObjectCreated(hoCheck))) Begin
Send CreateComObject of hoCheck
End
Set ComUserPassword Of hoCheck To "user-secret"
Get ComLoadFile Of hoCheck "qa_output/memo_encrypted_signed.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCheck To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatJsonObject)) To hoEmpty
If (Not(IsComObjectCreated(hoEmpty))) Begin
Send CreateComObject of hoEmpty
End
Get Create (RefClass(cComChilkatJsonObject)) To hoInfo
If (Not(IsComObjectCreated(hoInfo))) Begin
Send CreateComObject of hoInfo
End
Get pvComObject of hoEmpty to vEmpty
Get pvComObject of hoInfo to vInfo
Get ComProtection Of hoCheck "getInfo" vEmpty vInfo To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCheck To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComStringOf Of hoInfo "loaded.algorithm" To sTemp1
Showln "algorithm: " sTemp1
Get ComNumSignatures Of hoCheck To iTemp1
Showln "signatures: " iTemp1
Get Create (RefClass(cComChilkatJsonObject)) To hoSigInfo
If (Not(IsComObjectCreated(hoSigInfo))) Begin
Send CreateComObject of hoSigInfo
End
Get pvComObject of hoSigInfo to vSigInfo
Get ComVerifySignature Of hoCheck 0 vSigInfo To iVerified
Showln "signature verifies: " iVerified
// Signing an encrypted PDF. This one was opened with only the user password, and its
// permissions do not allow modifying, so another signature is refused.
Get pvComObject of hoCert to vCert
Get ComSetSigningCert Of hoCheck vCert To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCheck To sTemp1
Showln sTemp1
Procedure_Return
End
Get pvComObject of hoSigOpts to vSigOpts
Get ComSignPdf Of hoCheck vSigOpts "qa_output/memo_signed_twice.pdf" To iSuccess
If (iSuccess = False) Begin
Showln "A second signature was refused: the permissions do not allow it."
End
// Loaded with the owner password, the same PDF can be signed. It stays encrypted, and the
// first signature stays valid because the new one is added as an incremental update.
Get Create (RefClass(cComChilkatPdf)) To hoOwner
If (Not(IsComObjectCreated(hoOwner))) Begin
Send CreateComObject of hoOwner
End
Set ComUserPassword Of hoOwner To "user-secret"
Set ComOwnerPassword Of hoOwner To "owner-secret"
Get ComLoadFile Of hoOwner "qa_output/memo_encrypted_signed.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoOwner To sTemp1
Showln sTemp1
Procedure_Return
End
Get pvComObject of hoCert to vCert
Get ComSetSigningCert Of hoOwner vCert To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoOwner To sTemp1
Showln sTemp1
Procedure_Return
End
Get pvComObject of hoSigOpts to vSigOpts
Get ComSignPdf Of hoOwner vSigOpts "qa_output/memo_signed_twice.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoOwner To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatPdf)) To hoTwice
If (Not(IsComObjectCreated(hoTwice))) Begin
Send CreateComObject of hoTwice
End
Set ComUserPassword Of hoTwice To "user-secret"
Get ComLoadFile Of hoTwice "qa_output/memo_signed_twice.pdf" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoTwice To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComNumSignatures Of hoTwice To iTemp1
Showln "signatures after signing with owner rights: " iTemp1
Get pvComObject of hoSigInfo to vSigInfo
Get ComVerifySignature Of hoTwice 0 vSigInfo To iVerified
Showln "first signature still verifies: " iVerified
Get pvComObject of hoSigInfo to vSigInfo
Get ComVerifySignature Of hoTwice 1 vSigInfo To iVerified
Showln "second signature verifies: " iVerified
// Sample output:
// algorithm: aes-256
// signatures: 1
// signature verifies: True
// A second signature was refused: the permissions do not allow it.
// signatures after signing with owner rights: 2
// first signature still verifies: True
// second signature verifies: True
End_Procedure