Sample code for 30+ languages & platforms
PureBasic

FatturaPA XML Invoice Sign+Encrypt to P7M

See more Digital Signatures Examples

Demonstrates how to create a CAdES BES signed + encrypted invoice.xml.p7m for the Italian FatturaPA exchange system.

Chilkat PureBasic Downloads

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

Procedure ChilkatExample()

    success.i = 0

    ; This requires 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

    ; Use a digital certificate and private key from a PFX file (.pfx or .p12).
    pfxPath.s = "qa_data/pfx/cert_test123.pfx"
    pfxPassword.s = "test123"

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

    success = CkCert::ckLoadPfxFile(cert,pfxPath,pfxPassword)
    If success = 0
        Debug CkCert::ckLastErrorText(cert)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ; Provide the signing cert (with associated private key).
    success = CkCrypt2::ckSetSigningCert(crypt,cert)
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ; Indicate that SHA-256 should be used.
    CkCrypt2::setCkHashAlgorithm(crypt, "sha256")

    ; Specify the signed attributes to be included.
    ; (This is what makes it CAdES-BES compliant.)
    jsonSignedAttrs.i = CkJsonObject::ckCreate()
    If jsonSignedAttrs.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkJsonObject::ckUpdateInt(jsonSignedAttrs,"contentType",1)
    CkJsonObject::ckUpdateInt(jsonSignedAttrs,"signingTime",1)
    CkJsonObject::ckUpdateInt(jsonSignedAttrs,"messageDigest",1)
    CkJsonObject::ckUpdateInt(jsonSignedAttrs,"signingCertificateV2",1)
    CkCrypt2::setCkSigningAttributes(crypt, CkJsonObject::ckEmit(jsonSignedAttrs))

    inFile.s = "qa_data/xml/IT01234567890_11002.xml"
    sigFile.s = "qa_data/fatturapa/signed.p7m"

    ; Create the CAdES-BES signature, which contains the original data.
    success = CkCrypt2::ckCreateP7M(crypt,inFile,sigFile)
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkJsonObject::ckDispose(jsonSignedAttrs)
        ProcedureReturn
    EndIf

    ; Now we'll encrypt what was signed using FatturaPA's certificate (from a PEM file)
    encryptCert.i = CkCert::ckCreate()
    If encryptCert.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkCert::ckLoadFromFile(encryptCert,"qa_data/certs/fatturapa_cert.pem")
    If success = 0
        Debug CkCert::ckLastErrorText(encryptCert)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkJsonObject::ckDispose(jsonSignedAttrs)
        CkCert::ckDispose(encryptCert)
        ProcedureReturn
    EndIf

    CkCrypt2::setCkCryptAlgorithm(crypt, "pki")

    success = CkCrypt2::ckSetEncryptCert(crypt,encryptCert)
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkJsonObject::ckDispose(jsonSignedAttrs)
        CkCert::ckDispose(encryptCert)
        ProcedureReturn
    EndIf

    ; Indicate the underlying bulk encryption algorithm to be used:
    CkCrypt2::setCkPkcs7CryptAlg(crypt, "aes")
    CkCrypt2::setCkKeyLength(crypt, 128)

    ; There's one last option that could be set.  If is the RSA encryption encryption/padding scheme. 
    ; By default, RSAES_PKCS1-V1_5 is used.  If desired, the OaepPadding property could be set to 1 to
    ; use RSAES_OAEP.  (We'll leave it set at the default value of 0)
    CkCrypt2::setCkOaepPadding(crypt, 0)

    ; Everything is specified.  Encrypt the .p7m to create a new .p7m (which adds a layer of encryption around the opaque signature).
    ; The output is PKCS7 in binary DER format.
    success = CkCrypt2::ckCkEncryptFile(crypt,sigFile,"qa_output/signed_and_encrypted.p7m")
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkCert::ckDispose(cert)
        CkJsonObject::ckDispose(jsonSignedAttrs)
        CkCert::ckDispose(encryptCert)
        ProcedureReturn
    EndIf

    Debug "Success."


    CkCrypt2::ckDispose(crypt)
    CkCert::ckDispose(cert)
    CkJsonObject::ckDispose(jsonSignedAttrs)
    CkCert::ckDispose(encryptCert)


    ProcedureReturn
EndProcedure