Adding licensing to application
Optional licensing mechanism is provided to protect your application against unauthorized usage. This short tutorial explaints how to add licensing into your application.
How it works
- We create license file: Your application receives the XML license file containing list of licensed features.
- You check the license: Your application will verify the license file.
License file is encrypted using a random AES key which is encrypted by provided public RSA key. You must generate the public and private RSA key, while keeping the private RSA key secret.
The file is signed by Siemens Healthineers private RSA key. The signature can be verified by a public RSA key shared by a Siemens Healthineers Partner Manager.
- You activate licensed features: Your application will activate the licensed features.
Configure licensing in Developer Portal application
Prerequisites
- Created an application following one of these tutorials (linux container, python-based app)
- Licensing feature enabled by Siemens Healthineers Partner Manager
- License strings for your algorithms
- Public and private key for encryption
In the Configure app step , add following steps:
Switch to the License Selection tab, then turn on the Licensing.
Next, provide public key of the pair which is used to encrypt the AES key in the PEM format. Needs to be RSA key with Bit length of at least 2048. Afterwards provide license strings delimited by newline - these strings are used to represent specific features or entitlements that user or application are allowed to access. These are unique strings that correspond to specific licenses or features.
License handling flow in your application
These are steps to verify and extract information from license file:
- Decrypt AES key (first 256bytes) using your own private key.
- Decrypt encrypted content (byte 512 - EOF) using the decrypted AES key from step 1.
- Optional: Verify signature (bytes 256 - 512) using provided public RSA key from Siemens Healthineers Partner Manager
- Activate application features based on provided license/feature strings.
To know what to expect and when to activate licensed feature, an example of a license file that we generate is shown here
Example of handling license flow in your code in python :
def verify_signature(public_key, aes_key_encrypted, encrypted_content, signature):
data_to_verify = aes_key_encrypted + encrypted_content
# Verify the signature using the RSA public key
try:
public_key.verify(
signature,
data_to_verify,
padding.PKCS1v15(),
hashes.SHA512()
)
return True # Signature is valid
except Exception as e:
print(f"Verification failed: {e}")
return False # Signature is invalid
def main():
file_data = bytearray()
# Open the file in binary read mode
with open('license.dat', 'rb') as file:
# Read the entire file into the bytearray
file_data = file.read()
# Extract the key (first 256 bytes)
key = file_data[:256]
# Extract the signature (next 256 bytes)
signature = file_data[256:512]
# Extract the encrypted content (remaining bytes after the first 512 bytes)
encrypted_content = file_data[512:]
#Optional verify the key (SHA512)
is_verified = verify_signature(publickey, key, encrypted_content, signature)
print(f"Signature verified: {is_verified}")
#Decrypt the key
aes_key_decrypted = privatekey.Decrypt(key,padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
))
aes_key = aes_key_decrypted[:32] # 256 bits / 8 = 32 bytes
aes_iv = aes_key_decrypted[32:48] # 128 bits / 8 = 16 bytes
cipher = AES.new(aes_key, AES.MODE_CBC, aes_iv)
# Decrypt and unpad the content
xml = unpad(cipher.decrypt(encrypted_content), AES.block_size)
root = ET.fromstring(xml)
# Deserialize datetime
license_creation_datetime = datetime.fromisoformat(root.find('LicenseCreationDateTime').text)
license_expiration_datetime = datetime.fromisoformat(root.find('LicenseExpirationDateTime').text)
# Deserialize LicenseDetails
license_name = root.find('LicenseDetails/License/Name').text
License example
Below is a generated license file we create from your license strings. The license strings are present in LicenseDetails element in xml.
SystemFingerprint, MaterialNumber and SerialNumber are available only on syngo.via (Open Apps environment)