Key management
...
Integration Workflow
Upload AES-256 key to HSM and generate hashed & encrypted Tenant Secret
3 min
this section explains how to use the python script and excrypt manager to generate random aes 256 key components and upload it to the {{vectera}} hsm after uploading the key, the script will generate the hashed tenant secret and the encrypted tenant secret files by wrapping the aes 256 key with the salesforce 4096 rsa key python script below is the python script that will be used to generate a random aes 256 key hash the tenant secret wrap the aes 256 key with the salesforce 4096 key information needed (will be surrounded by "< >") hsm ip the ip of the hsm that the device running the script will be able to reach the hsm from crypto cipher import aes import socket import base64 import os import hashlib hsm ip = "\<hsm ip>" hsm port = 9000 def generate key parts and aes(part count=2, components per part=4, bytes per component=8) """ generates key parts made of components, xors all parts to form the final aes 256 key, produces salesforce sha 256 hash, and computes kcv """ all parts = \[] xor accumulator = bytearray(32) # start with all zeros; final aes key = xor of all part bytes print("\n=== generating key parts ===") for part idx in range(part count) part components = \[] part bytes = b'' print(f"\nkey part {part idx + 1} ") for comp idx in range(components per part) comp = os urandom(bytes per component) comp hex = comp hex() part components append(comp hex) part bytes += comp print(f" component {comp idx + 1} {comp hex}") \# expand 16 bytes → 32 bytes (salesforce needs 256 bit final key) \# we duplicate the 16 bytes to reach 32 bytes expanded part = part bytes + part bytes \# xor this part into the overall aes key accumulator xor accumulator = bytes(a ^ b for a, b in zip(xor accumulator, expanded part)) all parts append({ "part number" part idx + 1, "components" part components }) \# final aes 256 key aes key = bytes(xor accumulator) print("\nfinal aes key (hex) ", aes key hex() upper()) \# salesforce sha 256 tenant secret sha256 digest = hashlib sha256(aes key) digest() sha256 b64 = base64 b64encode(sha256 digest) decode() print("sha 256 digest (base64 for salesforce) ", sha256 b64) with open("hashed tenant secret b64", "w") as f f write(sha256 b64) print("hash of aes 256 key is saved to hashed tenant secret b64") \# compute kcv (first 2 bytes of aes ecb encrypt of zero block) cipher = aes new(aes key, aes mode ecb) encrypted = cipher encrypt(bytes(16)) kcv = encrypted\[ 2] hex() upper() print("key check value (kcv) ", kcv) return aes key, sha256 b64, kcv, all parts \# obtain how many key parts the user would like to user to generate the aes 256 key parts count = int(input("enter number of key parts ")) aes key, salesforce hash, kcv, parts = generate key parts and aes(key parts count) \# perform key wrapping of the aes256 key with salesforce public key \## grab input from user of which slot the public salesforce key and aes 256 key is located print("\nplease copy the components to futurex excrypt manager to generate am aes 256 key") print("also, make sure that the salesforce public key is uploaded to hsm") salesforce pub key slot = input("\nenter the slot number where the salesforce public key is stored in the hsm ") aes256 slot = input("\nenter the slot number where the aes256 key is stored in the hsm ") gpwb command = f"\[aogpwb;rc{salesforce pub key slot};bgbd{aes256 slot};as2;fs6;ce4;op1;]" print("\n➡️ sending (gpwb) ", gpwb command strip()) with socket create connection((hsm ip, hsm port)) as s s sendall(gpwb command encode()) response = s recv(8192) decode() # use large buffer for rsa wrapped data print("⬅️ raw response (gpwb) ", repr(response)) \# parse rj (wrapped key) and ae (check value) from the response wrapped key hex, check val = none, none if "bg" in response parts = response strip("\[]") split(";") wrapped key hex = next((p\[2 ] for p in parts if p startswith("bg")), none) check val = next((p\[2 ] for p in parts if p startswith("ae")), none) if wrapped key hex wrapped b64 = base64 b64encode(bytes fromhex(wrapped key hex)) decode() print(f"\n encrypted tenant secret (base64) \n{wrapped b64}") with open("encrypted tenant secret b64", "w") as f2 f2 write(wrapped b64) print("tenant secret encrypted saved to encrypted secret encrypted b64") print(f"\n length in bytes ", len(base64 b64decode(wrapped b64))) if check val print(f"check value (ae) {check val}") upload aes 256 random key to {{vectera}} download the script above and run it it will first ask how many key parts you would like to generate the amount of components outputted will depend on the number of key parts chosen for example, the output below contains 4 components because key parts value was 1 key part 1 component 1 d94b0bc9b794c5ac component 2 9bc6504068a32759 component 3 2a63f976a46a1b14 component 4 c9c1ae5ed2f590a9 on the excrypt manager, select key management , and under "key table" select edit key storage go to an available key slot and select insert key select symmetric key wizard and select ok for "key parts ", select the same number you entered for the python script for "major key to be used ", select pmk for "modifier/header ", select 2 dek for "key type/length ", select aes 256 for "key usage", select encrypt & decrypt enter a key label select preferred security usages select next > enter the components based on the output from the python script important to avoid the plaintext components of the key being copied to memory on the device, copy the components text by hand instead of using copy and paste select next > and next > again note make sure that the "checksum standard " value matches python's output kcv value select finish attain the hash tenant secret and encrypted tenant secret files after uploading the aes 256 key to the hsm, go back to the python script in the directory which the python script is located, the hash tenant secret b64 will be produced the script will ask to input the slot number of where the salesforce public key is located the script will then ask to input the slot number of where the aes 256 key is located that was uploaded in the previous steps the python script will finish and output the wrapped tenant secret to encrypted tenant secret b64