Back to Contents


The Encryption class

Summary

See also: The Genero Web Services XML Library


Syntax

The Encryption class provides methods to encrypt and decrypt XML documents, nodes or symmetric keys. It follows the XML-Encryption specifications.

The status is set to zero after a successful method call.

Syntax

xml.Encryption
 

Methods


Creation methods

Class Methods
Name Description
xml.Encryption.Create()
   RETURNING xml.Encryption
Constructor of an Encryption object.
Returns a Encryption object or NULL.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


Key and certificate setting methods

Object Methods
Name Description
setKey(
  key xml.CryptoKey)
Assigns a copy of the symmetric key to this Encrytion object. Any further XML document or node encryption or decryption will use that symmetric key.

When decrypting a XML document that has an embedded symmetric key, the embedded key will be used instead.

Throws an exception in case of errors, and updates status with an error code.

getEmbeddedKey()
   RETURNING xml.CryptoKey
Returns a copy of the embedded symmetric key that was used in the last decryption operation, or NULL if there is none.

An embedded symmetric key is always encrypted, and needs therefore a key-encryption key to be set in order to decrypt it.

Throws an exception in case of errors, and updates status with an error code.

setKeyEncryptionKey(
  key xml.CryptoKey)
Assigns a copy of the key-encryption key to this Encrytion object.

Any further XML encryption will use that key-encryption key to encrypt the symmetric key set with setKey() within the resulting XML, and any further XML decryption will use that key-encryption key to decrypt the embedded symmetric key.

  • NULL is allowed, meaning that embedded symmmetric keys will not be encrypted nor decrypted anymore, assuming that they have been exchanged in another way.
  • Only public or private RSA keys, or key-wrap keys are allowed.
  • Public RSA keys can encrypt but not decrypt.

Throws an exception in case of errors, and updates status with an error code.

setCertificate(
  cert xml.CryptoX509)
Assigns a copy of the X509 certificate to this Encryption object. The certificate will then be added to any further XML document or node encryption.
  • NULL is allowed to avoid the certificate being added. 
  • To encrypt using a certificate, you must use the createPublicKey() method of the X509 class to obtain the public key embedded in the certificate, and then provide it to the encryption object with above setKeyEncryptionKey() method.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


XML elements encryption and decryption methods

Object Methods
Name Description
encryptElement(
  node xml.DomNode)
Encrypts the ELEMENT DomNode node and all its children using the symmetric key.

The ELEMENT DomNode node and all its children are replaced at the same place in the XML document with the resulting EncryptedData node.

Throws an exception in case of errors, and updates status with an error code.

decryptElement(
  enc xml.DomNode)
Decrypts the EncryptedData DomNode enc using the symmetric key.

The encrypted DomNode enc is replaced at the same place in the XML document with the resulting ELEMENT DomNode and its children.

Throws an exception in case of errors, and updates status with an error code.

encryptElementContent(
  node xml.DomNode)
Encrypts all child nodes of the ELEMENT DomNode node using the symmetric key.

The child nodes of the ELEMENT DomNode node are replaced at the same place in the XML document with the resulting EncryptedData node.

Throws an exception in case of errors, and updates status with an error code.

decryptElementContent(
  enc xml.DomNode)
Decrypts the EncryptedData DomNode enc using the symmetric key.

The encrypted DomNode enc is replaced at the same place in the XML document with the resulting child nodes.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


Detached XML elements encryption and decryption methods

Object Methods
Name Description
encryptElementDetached(
  node xml.DomNode)
   RETURNING xml.DomNode
Encrypts the ELEMENT DomNode node and all its children using the symmetric key, and returns them as one new EncryptedData node.

The resulting DomNode isn't added at any place in the XML document. It's up to the user to insert it at the right place, and to remove the nodes in clear form.

Throws an exception in case of errors, and updates status with an error code.

decryptElementDetached(
  enc xml.DomNode)
   RETURNING xml.DomNode
Decrypts the EncryptedData DomNode enc using the symmetric key, and returns it in a new ELEMENT node.

The resulting DomNode and its children aren't added at any place in the XML document. It's up to the user to insert it at the right place, and to remove the encrypted node.

Throws an exception in case of errors, and updates status with an error code.

encryptElementContentDetached(
  node xml.DomNode)
   RETURNING xml.DomNode
Encrypts all child nodes of the ELEMENT DomNode node using the symmetric key, and returns them as one new EncryptedData node.

The resulting DomNode isn't added at any place in the XML document. It's up to the user to insert it at the right place, and to remove the nodes in clear form.

Throws an exception in case of errors, and updates status with an error code.

decryptElementContentDetached(
  enc xml.DomNode)
   RETURNING xml.DomNode
Decrypts the EncryptedData DomNode enc using the symmetric key, and returns all its children in one new DOCUMENT_FRAGMENT_NODE node.

The resulting child nodes aren't added at any place in the XML document. It's up to the user to insert it at the right place, and to remove the encrypted node.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


Key encryption and decryption methods

Object Methods
Name Description
encryptKey(
  key xml.CryptoKey)
   RETURNING xml.DomDocument
Encrypts the given symmetric key as an EncryptedKey node and returns it as root node of a new XML document. The key-encryption key must been set otherwise it will fail.

Depending on the feature set on the key-encryption key, the returned XML document will contain an additional KeyInfo node.

Throws an exception in case of errors, and updates status with an error code.

decryptKey(
  xml xml.DomDocument,
  url STRING)
   RETURNING xml.CryptoKey
Decrypts the EncryptedKey as root in the given XML document, and returns a new CryptoKey of given kind.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


String encryption and decryption methods

The following methods don't belong to the XML encryption specification, but are helper functions to allow 4GL application to encrypt and decrypt short passwords with RSA keys, or big strings by using symmetric keys. Notice that a common way to encrypt data is to use symmetric keys, and to use RSA keys to encrypt the symmetric key value.

Class Methods
Name Description
xml.Encryption.EncryptString(
  key xml.CryptoKey,
  str STRING)
   RETURNING STRING
Encrypts the string str, using the symmetric key key, and returns the encrypted string encoded in BASE64.

The key must be of usage: encryption.

Throws an exception in case of errors, and updates status with an error code.

xml.Encryption.DecryptString(
  key xml.CryptoKey,
  str STRING)
   RETURNING STRING
Decrypts the encrypted string str encoded in BASE64, using the symmetric key key, and returns the string in clear text.

The key must be of usage: encryption.

Throws an exception in case of errors, and updates status with an error code.

xml.Encryption.RSAEncrypt(
  key STRING,
  str STRING)
    RETURNING STRING
Encrypts the string str using the RSA key key and returns it encoded in BASE64; where key is the filename of a RSA public or private key in PEM format or an entry in the FGLPROFILE file, and where str is the string to be encrypted.

RSA encryption is only intended to short strings that cannot exceed the size of the RSA key minus 12 bytes. For instance, if you have a RSA key of 512 bits, you password cannot exceed 512/8-12 = 52 bytes. If you need to handle big strings, you must use symmetric keys and the method EncryptString(). However, you can use RSA keys to encrypt symmetric key values.

Throws an exception in case of errors, and updates status with an error code.

xml.Encryption.RSADecrypt(
  key STRING,
  enc STRING)
    RETURNING STRING
Decrypts the BASE64 encrypted string enc using the RSA key key and returns it in clear text;  where key is the filename of a RSA private key in PEM format or an entry in the FGLPROFILE file, and where enc is a string that was encrypted with the fglpass tool or with the above method.

RSA decryption is only intended to short strings that cannot exceed the size of the RSA key minus 12 bytes. For instance, if you have a RSA key of 512 bits, you password cannot exceed 512/8-12 = 52 bytes. If you need to handle big strings, you must use symmetric keys and the method DecryptString(). However, you can use RSA keys to decrypt symmetric key values.

Warning! YOU MUST PAY ATTENTION TO RESTRICT ACCESS TO THAT RSA PRIVATE KEY FILE ONLY TO THE PERSON OR GROUP OF PERSON AUTHORIZED.

If the RSA private key is protected with a password the recommended way is to unprotect it with the openssl tool and to put the key file on a restricted file system. But you can also use a script or the fglpass agent to provide the password to the application.

For example, you can encrypt a database password with the fglpass tool and store it in the FGLPROFILE file, then you can decrypt it with the base.Application.getResourceEntry() and the xml.Encryption.RSADecrypt() method to connect to the database.

Throws an exception in case of errors, and updates status with an error code.

Back to the top


Examples

Example 1 : Encrypt a XML node with a symmetric AES128 key

01 IMPORT xml
02
03 MAIN
04 DEFINE doc xml.DomDocument
05 DEFINE root xml.DomNode
06 DEFINE enc xml.Encryption
07 DEFINE symkey xml.CryptoKey
08 LET doc = xml.DomDocument.Create()
09 # Notice that white spaces are significant in crytography,
10 # therefore it is recommended that you remove unnecessary ones
11 CALL doc.setFeature("whitespace-in-element-content",FALSE)
12 TRY
13 # Load XML file to be encrypted
14   CALL doc.load("XMLFileToBeEncrypted.xml")
15   LET root = doc.getDocumentElement()
16   # Create symmetric AES128 key for XML encryption purposes
17   LET symkey = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmlenc#aes128-cbc")
18   CALL symkey.setKey(">secretpassword<") # password of 128 bits
19   CALL symKey.setFeature("KeyName","MySecretKey") # Name the password in order to identify the key (Not mandatory)
20   # Encrypt the entire document
21   LET enc = xml.Encryption.Create()
22   CALL enc.setKey(symkey) # Set the symmetric key to be used
23   CALL enc.encryptElement(root) # Encrypt
24   # Save encrypted document back to disk
25   CALL doc.setFeature("format-pretty-print",TRUE)
26   CALL doc.save("EncryptedXMLFile.xml")
27 CATCH
28    DISPLAY "Unable to encrypt XML file :",STATUS
29   END TRY
30 END MAIN

Example 2 : Decrypt a XML node with a symmetric AES128 key

01 IMPORT xml
02
03 MAIN
04   DEFINE doc xml.DomDocument
05   DEFINE node xml.DomNode
06   DEFINE enc xml.Encryption
07   DEFINE symkey xml.CryptoKey
08   DEFINE list xml.DomNodeList
09   DEFINE str String
10   LET doc = xml.DomDocument.Create()
11   # Notice that whitespaces are significants in crytography,
12   # therefore it is recommended to remove unnecessary ones
13   CALL doc.setFeature("whitespace-in-element-content",FALSE)
14   TRY
15    # Load encrypted XML file
16     CALL doc.load("EncryptedXMLFile.xml")
17     # Retrieve encrypted node (if any) from the document
18     LET list = doc.getElementsByTagNameNS("EncryptedData","http://www.w3.org/2001/04/xmlenc#")
19     IF list.getCount()==1 THEN
20      LET node = list.getItem(1)
21     ELSE
22       DISPLAY "No encrypted node found"
23       EXIT PROGRAM
24     END IF
25     # Check if symmetric key name matches the expected "MySecretKey" (Not mandatory)
26     LET list = node.selectByXPath("dsig:KeyInfo/dsig:KeyName[position()=1 and text()=\"MySecretKey\"]","dsig","http://www.w3.org/2000/09/xmldsig#")
27     IF list.getCount()!=1 THEN
28      DISPLAY "Key name doesn't match"
29      EXIT PROGRAM
30     END IF
31     # Create symmetric AES128 key for XML decryption purpose
32     LET symkey = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmlenc#aes128-cbc")
33     CALL symkey.setKey(">secretpassword<") # password of 128 bits
34     # Decrypt the entire document
35     LET enc = xml.Encryption.Create()
36     CALL enc.setKey(symkey) # Set the symmetric key to be used
37     CALL enc.decryptElement(node) # Decrypt
38     # Save encrypted document back to disk
39     CALL doc.setFeature("format-pretty-print",TRUE)
40     CALL doc.save("DecryptedXMLFile.xml")
41   CATCH
42     DISPLAY "Unable to decrypt XML file :",STATUS
43   END TRY
44 END MAIN

Example 3 : Encrypt a XML node with a generated symmetric key protected with the public RSA key within a X509 certificate

01 IMPORT xml
02
03 MAIN
04   DEFINE doc xml.DomDocument
05   DEFINE root xml.DomNode
06   DEFINE enc xml.Encryption
07   DEFINE symkey xml.CryptoKey
08   DEFINE kek xml.CryptoKey
09   DEFINE cert xml.CryptoX509
10   LET doc = xml.DomDocument.Create()
11   # Notice that whitespaces are significants in crytography,
12   # therefore it is recommended to remove unnecessary ones
13   CALL doc.setFeature("whitespace-in-element-content",FALSE)
14   TRY
15     # Load XML file to be encrypted
16     CALL doc.load("XMLFileToBeEncrypted.xml")
17     LET root = doc.getDocumentElement()
18     # Load the X509 certificate and retrieve the public RSA key for key-encryption purpose
19     LET cert = xml.CryptoX509.Create()
20     CALL cert.load("RSA1024Certificate.crt")
21     LET kek = cert.createPublicKey("http://www.w3.org/2001/04/xmlenc#rsa-1_5")
22     # Generate symmetric key for XML encryption purpose
23     LET symkey = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmlenc#aes256-cbc")
24     CALL symkey.generateKey(NULL)
25     # Encrypt the entire document
26     LET enc = xml.Encryption.Create()
27     CALL enc.setKey(symkey) # Set the symmetric key to be used
28     CALL enc.setKeyEncryptionKey(kek) # Set the key-encryption key to be used for protecting the symmetric key
29     CALL enc.setCertificate(cert) # Set the certificate to be added (not mandatory)
30     CALL enc.encryptElement(root) # Encrypt
31     # Save encrypted document back to disk
32     CALL doc.setFeature("format-pretty-print",TRUE)
33     CALL doc.save("EncryptedXMLFile.xml")
34   CATCH
35     DISPLAY "Unable to encrypt XML file :",STATUS
36   END TRY
37 END MAIN

Example 4 : Decrypt a XML node encrypted with a symmetric key protected with a private RSA key

01 IMPORT xml
02
03 MAIN
04   DEFINE doc xml.DomDocument
05   DEFINE node xml.DomNode
06   DEFINE enc xml.Encryption
07   DEFINE symkey xml.CryptoKey
08   DEFINE kek xml.CryptoKey
09   DEFINE list xml.DomNodeList
10   LET doc = xml.DomDocument.Create()
11   # Notice that whitespaces are significants in crytography,
12   # therefore it is recommended to remove unnecessary ones
13   CALL doc.setFeature("whitespace-in-element-content",FALSE)
14   TRY
15     # Load encrypted XML file    
16 CALL doc.load("EncryptedXMLFile.xml")
17     # Retrieve encrypted node (if any) from the document
18     LET list = doc.getElementsByTagNameNS("EncryptedData","http://www.w3.org/2001/04/xmlenc#")
19     IF list.getCount()==1 THEN
20      LET node = list.getItem(1)
21     ELSE
22       DISPLAY "No encrypted node found"
23       EXIT PROGRAM
24     END IF
25     # Load the private RSA key
26     LET kek = xml.CryptoKey.create("http://www.w3.org/2001/04/xmlenc#rsa-1_5")
27     CALL kek.loadPEM("RSA1024Key.pem")
28     # Decrypt the entire document
29     LET enc = xml.Encryption.Create()
30     CALL enc.setKeyEncryptionKey(kek) # Set the key-encryption key to decrypted the protected symmetric key
31     CALL enc.decryptElement(node) # Decrypt
32     # Retrieve the embedded symmetric key for futher usage and display info about it
33     LET symkey = enc.getEmbeddedKey()
34     DISPLAY "Key size (in bytes) : ",symkey.getSize() # displays 1024
35     DISPLAY "Key type : ",symkey.getType() # displays SYMMETRIC
36     DISPLAY "Key usage : ",symkey.getUsage() # displays ENCRYPTION
37     # Save encrypted document back to disk
38     CALL doc.setFeature("format-pretty-print",TRUE)
39     CALL doc.save("DecryptedXMLFile.xml")
40   CATCH
41     DISPLAY "Unable to decrypt XML file :",STATUS
42   END TRY
43 END MAIN

Note: All keys or certificates in PEM or DER format were created with the OpenSSL tool.

Back to the top