PureBasic Requires Chilkat v11.7.0+
PureBasic
Encrypt a PDF for a Certificate Instead of a Password
See more PDF Protection Examples
Demonstrates certificate security, where a PDF is encrypted for one or more recipients and each opens it with their own certificate and private key. No password is involved. Only the public certificate of a recipient is needed to encrypt. Each recipient has its own permissions, and the changeSecurity permission gives a recipient owner rights. PreLoadCheck tells an application that a file is certificate-encrypted and which certificates can open it. A PDF that cannot be opened, because no matching certificate and private key were provided, fails to load.Chilkat PureBasic Downloads
IncludeFile "CkCert.pb"
IncludeFile "CkPdf.pb"
IncludeFile "CkJsonObject.pb"
Procedure ChilkatExample()
success.i = 0
; 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 recipient's certificate. Only the public certificate is needed to encrypt.
recipient.i = CkCert::ckCreate()
If recipient.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadFromFile(recipient,"qa_data/certs/recipient.cer")
If success = 0
Debug CkCert::ckLastErrorText(recipient)
CkCert::ckDispose(recipient)
ProcedureReturn
EndIf
pdf.i = CkPdf::ckCreate()
If pdf.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPdf::ckLoadFile(pdf,"qa_data/pdf/two_page_memo.pdf")
If success = 0
Debug CkPdf::ckLastErrorText(pdf)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
ProcedureReturn
EndIf
; Call AddEncryptCert once for each recipient.
success = CkPdf::ckAddEncryptCert(pdf,recipient)
If success = 0
Debug CkPdf::ckLastErrorText(pdf)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
ProcedureReturn
EndIf
; recipientPermissions[0] belongs to the first certificate added. changeSecurity gives that
; recipient owner rights, so the file can be managed later.
json.i = CkJsonObject::ckCreate()
If json.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckUpdateString(json,"method","certificate")
CkJsonObject::ckUpdateBool(json,"recipientPermissions[0].changeSecurity",1)
jsonOut.i = CkJsonObject::ckCreate()
If jsonOut.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPdf::ckProtection(pdf,"encrypt",json,jsonOut)
If success = 0
Debug CkPdf::ckLastErrorText(pdf)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
ProcedureReturn
EndIf
Debug "method: " + CkJsonObject::ckStringOf(jsonOut,"pending.method")
Debug "algorithm: " + CkJsonObject::ckStringOf(jsonOut,"pending.algorithm")
Debug "recipients: " + Str(CkJsonObject::ckSizeOfArray(jsonOut,"pending.recipients"))
success = CkPdf::ckWriteFile(pdf,"qa_output/memo_for_recipient.pdf")
If success = 0
Debug CkPdf::ckLastErrorText(pdf)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
ProcedureReturn
EndIf
; PreLoadCheck says how the file is protected, without loading it.
reader.i = CkPdf::ckCreate()
If reader.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
info.i = CkJsonObject::ckCreate()
If info.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPdf::ckPreLoadCheck(reader,"qa_output/memo_for_recipient.pdf",info)
If success = 0
Debug CkPdf::ckLastErrorText(reader)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
ProcedureReturn
EndIf
Debug "saved file, method: " + CkJsonObject::ckStringOf(info,"method")
Debug "saved file, recipients: " + Str(CkJsonObject::ckSizeOfArray(info,"recipients"))
; The recipient opens it with the certificate and its private key, here from a .pfx file.
; (On Windows, a certificate that is installed in the Windows certificate store with its private
; key is found automatically when the PDF is loaded, and SetDecryptCert is not needed for it.)
myCert.i = CkCert::ckCreate()
If myCert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadPfxFile(myCert,"qa_data/pfx/recipient.pfx","pfx-password")
If success = 0
Debug CkCert::ckLastErrorText(myCert)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
CkCert::ckDispose(myCert)
ProcedureReturn
EndIf
success = CkPdf::ckSetDecryptCert(reader,myCert)
If success = 0
Debug CkPdf::ckLastErrorText(reader)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
CkCert::ckDispose(myCert)
ProcedureReturn
EndIf
success = CkPdf::ckLoadFile(reader,"qa_output/memo_for_recipient.pdf")
If success = 0
Debug CkPdf::ckLastErrorText(reader)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
CkCert::ckDispose(myCert)
ProcedureReturn
EndIf
empty.i = CkJsonObject::ckCreate()
If empty.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
loadedInfo.i = CkJsonObject::ckCreate()
If loadedInfo.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPdf::ckProtection(reader,"getInfo",empty,loadedInfo)
If success = 0
Debug CkPdf::ckLastErrorText(reader)
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
CkCert::ckDispose(myCert)
CkJsonObject::ckDispose(empty)
CkJsonObject::ckDispose(loadedInfo)
ProcedureReturn
EndIf
Debug "opened with: " + CkJsonObject::ckStringOf(loadedInfo,"loaded.openedWith")
Debug "pages: " + Str(CkPdf::ckNumPages(reader))
; Sample output:
; method: certificate
; algorithm: aes-256
; recipients: 1
; saved file, method: certificate
; saved file, recipients: 1
; opened with: certificate
; pages: 2
CkCert::ckDispose(recipient)
CkPdf::ckDispose(pdf)
CkJsonObject::ckDispose(json)
CkJsonObject::ckDispose(jsonOut)
CkPdf::ckDispose(reader)
CkJsonObject::ckDispose(info)
CkCert::ckDispose(myCert)
CkJsonObject::ckDispose(empty)
CkJsonObject::ckDispose(loadedInfo)
ProcedureReturn
EndProcedure