Keys in hardware: encryption using an HSM
In many cases, confidential data, e.g. personal, access, financial data or company secrets, have to be encrypted and stored in server or cloud applications. Unauthorised access by an attacker, but also system or backup administrators can therefore be prevented.
Many programming languages provide functions or libraries to facilitate data encryption. The key is either hidden in the file system or compiled in applications. For professional attackers, extracting the keys is no big challenge. Therefore, the protection of the keys enormously important in order to ensure a secure use of cryptography. The necessary keys have to be safeguarded in a medium, which makes an extraction impossible for unauthorised persons. Such a secure key storage medium is called hardware-security-module or HSM.
Im folgenden Beispiel wird gezeigt, wie man in Python
- in einem HSM einen symmetrischen AES Schlüssel (AES-256) generiert,
- den generierten Schlüssel für eine HSM-basierte Datenverschlüsselung nutzt und
- den verschlüsselten Inhalt mit Hilfe des HSMs wieder entschlüsselt.
Als HSM nutzen wir die se.SAM™ N200 Crypto Appliance über die integrierte REST-API, bei der wir die Ergebnisse per JSON Objekt zurückerhalten. Für die ersten Schritte empfehlen wir die kostenfreie Version von Postman.
#!/usr/bin/python3 import requests import json url = 'http://192.168.178.49/n200/web/postv1' # optional: url = 'https://192.168.178.49/n200/web/postv1' headers = { 'Authorization': 'Basic YWRtaW46YWRtaW4=' } # admin / admin core = "1" pin = "pin123456"
## Generate Key payload = {'command': 'gensymkey', 'core': core, 'keysize': '256', 'acl': 'FFFF', 'pin': pin} response = requests.request("POST", url, headers=headers, data=payload) if response.status_code != 200: print(response.status_code) print(response.text) exit() jsonreturns = json.loads(response.text) keyid = jsonreturns['result'] print("Generated keyid: %s" % keyid)
## HSM Encrypt Data payload={'command':'encrypt', 'core': core, 'keyid' : keyid, 'pin': pin, 'mode': 'ECB', 'cleartext_data': 'This is the secret text that will be encrypted by the network HSM'} response = requests.request("POST", url, headers=headers, data=payload) if response.status_code != 200: print(response.status_code) print(response.text) exit() jsonreturns = json.loads(response.text) cipher_data = jsonreturns['result'] print("Cipher data: %s" % cipher_data) # STORE cipher_data in file or database now! # # RELOAD cipher_data from file or database once required…
## HSM Decrypt Data payload={'command': 'decrypt', 'core': core, 'keyid': keyid, 'pin': pin, 'mode': 'ECB', 'cipher_data': cipher_data} response = requests.request("POST", url, headers=headers, data=payload) if response.status_code != 200: print(response.status_code) print(response.text) exit() jsonreturns = json.loads(response.text) cleartext_data = jsonreturns['result'] print("Cleartext data: %s" % cleartext_data)
Die Vorteile des Beispiels liegen auf der Hand:
- Nur berechtige Anwendungen (siehe Authorisierungsheader, zusätzlich IP-Adressen Check oder MFA-Schutz) können das HSM benutzen.
- Anwendungen benötigen zusätzliche Daten für die Ver- und Entschlüsselung, die einmalig gespeichert werden müssen.
- Schlüssel-ID/ keyid
- Individuelle PIN passend für die Schlüssel-ID
- Die Daten werden mit dem richtigen Schlüssel am HSM verschlüsselt und zurückgeliefert.
- Der Schlüssel verlässt niemals das HSM.
- Die Schlüsselbenutzung am HSM wird protokolliert und überwacht.
- Der Security-Administrator kann den Zugriff auf Schlüssel jederzeit untersagen. Somit bleibt die Verschlüsselung – auch für externe Dienste oder Cloud-Anwendungen – unter vollständiger Kontrolle durch das Unternehmen.
Der Sourcecode ist von der sematicon AG erstellt und darf frei genutzt werden.