Sample code for 30+ languages & platforms
PureBasic

A3/A4 Certificate to Create and Verify an Opaque PKCS7/CMS Signature

See more Digital Signatures Examples

Demonstrates how to use an A3 or A4 certificate w/ private key on a smartcard or token to create a PKCS7 opaque signature, and also how to verify an opaque signature.

An opaque signature is different than a detached PKCS7 signature in that it contains the original data. Verifying an opaque signature retrieves the original content.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkCrypt2.pb"
IncludeFile "CkCert.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This example assumes the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    crypt.i = CkCrypt2::ckCreate()
    If crypt.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; A certificate and private key is needed to create a signature.
    ; Chilkat provides many different ways to load a certificate and private key, such
    ; as from a smartcards and hardware tokens, PFX/.p12, Java keystore, JWK, Windows registry-based certificate stores, and other sources.
    ; This example will load the default certificate from the smartcard that is currently in
    ; the smartcard reader.

    cert.i = CkCert::ckCreate()
    If cert.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; If the smartcard or token requires a PIN, we can set it here to avoid the dialog...
    CkCert::setCkSmartCardPin(cert, "000000")

    success = CkCert::ckLoadFromSmartcard(cert,"")
    If success <> 1
        Debug CkCert::ckLastErrorText(cert)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ; Tell it to use the cert and private key we've loaded.
    success = CkCrypt2::ckSetSigningCert(crypt,cert)
    If success <> 1
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ; Indicate we want the opaque signature in base64 format:
    CkCrypt2::setCkEncodingMode(crypt, "base64")

    ; Sign the string using the "utf-8" byte representation:
    CkCrypt2::setCkCharset(crypt, "utf-8")

    ; Create the opaque signature:
    originalData.s = "This is the string to be signed."
    opaqueSig.s = CkCrypt2::ckOpaqueSignStringENC(crypt,originalData)
    If CkCrypt2::ckLastMethodSuccess(crypt) <> 1
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    Debug opaqueSig

    ; The output looks like this:
    ; MIIPgQYJKoZIhvcNAQcCoIIPcjCCD24CAQExCzAJBgUrDgMCGgUAMC8GCSqGSIb3DQEHAaAiBCBUaGlzIGlzIHRoZSBzdHJpbmcgdG8gYmUgc...

    ; ----------------------------------------------------------------------------------------------
    ; Now let's verify the signature and retrieve the original data.
    ; We'll use a new Crypt2 object to keep things completely separate...

    vCrypt.i = CkCrypt2::ckCreate()
    If vCrypt.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; We only need the certificate to verify a signature (and extract the data from
    ; an opaque signature).  The public key is always embedded within a certificate.
    success = CkCrypt2::ckSetVerifyCert(vCrypt,cert)
    If success <> 1
        Debug CkCrypt2::ckLastErrorText(vCrypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkCrypt2::ckDispose(vCrypt)
        ProcedureReturn
    EndIf

    CkCrypt2::setCkEncodingMode(vCrypt, "base64")
    CkCrypt2::setCkCharset(vCrypt, "utf-8")

    extractedData.s = CkCrypt2::ckOpaqueVerifyStringENC(vCrypt,opaqueSig)
    If CkCrypt2::ckLastMethodSuccess(vCrypt) <> 1
        Debug CkCrypt2::ckLastErrorText(vCrypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkCrypt2::ckDispose(vCrypt)
        ProcedureReturn
    EndIf

    Debug "The extracted data: " + extractedData

    ; The output is:
    ; The extracted data: This is the string to be signed.


    CkCrypt2::ckDispose(crypt)
    CkCert::ckDispose(cert)
    CkCrypt2::ckDispose(vCrypt)


    ProcedureReturn
EndProcedure