Powerbuilder Encryption – In einem aktuellen Projekt wurde die Anforderung gestellt, einen String, welcher mittels Rijndael Algorithmus verschlüsselt wurde, zu entschlüsseln. In weiterer Folge sollte damit die korrekte Authentifizierung beim Server durchführt werden. Im folgenden Artikel soll gezeigt werden, wie mittels Powerbuilder der Encrytion Algorithmen implementiert werden konnte.
Als Programmiertool wurde SAP Powerbuilder in der Version 12.6 eingesetzt.
Was ist grundsätzlich eine Rijndael Verschlüsselung?
Rijndael (Quelle Wikipedia – https://de.wikipedia.org/wiki/Advanced_Encryption_Standard abgerufen am 23.4.2017):
Der Advanced Encryption Standard (AES) ist eine Blockchiffre, die als Nachfolger für DES im Oktober 2000 vom National Institute of Standards and Technology (NIST) als Standard bekanntgegeben wurde. Nach seinen Entwicklern Joan Daemen und Vincent Rijmen wird AES auch Rijndael-Algorithmus genannt (gesprochen wie dt. räindahl). Es handelt sich um ein symmetrisches Verschlüsselungsverfahren, d. h. der Schlüssel zum Ver- und Entschlüsseln ist identisch. Der Rijndael-Algorithmus besitzt variable, voneinander unabhängige Block- und Schlüssellängen von 128, 160, 192, 224 oder 256 Bit. Rijndael bietet ein sehr hohes Maß an Sicherheit; erst mehr als zehn Jahre nach seiner Standardisierung wurde der erste theoretisch interessante, praktisch aber nicht relevante Angriff gefunden. AES schränkt die Blocklänge auf 128 Bit und die Wahl der Schlüssellänge auf 128, 192 oder 256 Bit ein. Die Bezeichnungen der drei AES-Varianten AES-128, AES-192 und AES-256 beziehen sich jeweils auf die gewählte Schlüssellänge. Der Algorithmus ist frei verfügbar und darf ohne Lizenzgebühren eingesetzt sowie in Soft- und Hardware implementiert werden. AES-192 und AES-256 sind in den USA für staatliche Dokumente mit höchster Geheimhaltungsstufe zugelassen. Rijndael ist eine als Substitutions-Permutations-Netzwerk entworfene Blockchiffre. Bei Rijndael können Blocklänge und Schlüssellänge unabhängig voneinander die Werte 128, 160, 192, 224 oder 256 Bits erhalten, während bei AES die Einschränkung der festgelegten Blockgröße von 128 Bit und der Schlüsselgröße von 128, 192 oder 256 Bit gilt. Jeder Block wird zunächst in eine zweidimensionale Tabelle mit vier Zeilen geschrieben, deren Zellen ein Byte groß sind. Die Anzahl der Spalten variiert somit je nach Blockgröße von 4 (128 Bits) bis 8 (256 Bits). Jeder Block wird nun nacheinander bestimmten Transformationen unterzogen. Aber anstatt jeden Block einmal mit dem Schlüssel zu verschlüsseln, wendet Rijndael verschiedene Teile des erweiterten Originalschlüssels nacheinander auf den Klartext-Block an. Die Anzahl r dieser Runden variiert und ist von der Schlüssellänge k und Blockgröße b abhängig (beim AES also nur von der Schlüssellänge).
Die Umsetzung erlaubte keine externen OLE/COM Objekte. So musste die Implementierung mittels verfügbarer WinAPI Funktionen durchgeführt werden.
Einen Überblick über die WinAPI Crypto Funktionen, welche von Microsoft unterstützt werden, kann hier ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa380252%28v=vs.85%29.aspx ) nachgelesen werden.
Die Vorgaben sind wie folgt:
- Message (String) liegt im Base64 Format vor
- Rijndael Verschlüsselung
- Unicode Passwort – Padding mit Zeros auf 32 Byte
- Initial Vektor mit 16 Byte
Somit sind die Fakten für die Implementierung fixiert:
- AES256 Alorithmus
- Keysize = 32 Byte
- Blocklänge 16 Bit
- Passwort = Key (normalerweise wird der Key über einen Hash aus dem Passwort generiert)
Powerbuilder Encryption Umsetzung (Auszug):
Zuerst die Base64 Message decoden und in einen Blob übertragen
lblb_Message = of_decode64_blob(as_message, as_error)
Das Passwort mit Zeros auffüllen – Gesamtlänge des Keys = 32 Byte
lblb_Password = Blob(as_password, EncodingUTF16LE!) lblb_zero = blob(bt_zero) ll_padding = 32 - len(lblb_Password) for ll_i = 1 to ll_padding lblb_Password = lblb_Password + lblb_zero next
Verwende AES256 – Algo
lul_AlgId = CALG_AES_256
Zuerst muss ein Crypto Kontext angefordert werden
CryptAcquireContext(iul_hProv, 0, "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT + CRYPT_NEWKEYSET)
Anschließend muss das Password bzw in diesem Fall der Key imporiert werden (keyBlob -> Passwort ByteArray mit einer Länge von 32 Bytes)
CryptImportKey(iul_hProv, keyBlob, lul_KeyLen, 0, 0, iul_hKey)
Initialize Vector = ersten 16 Byte vom Password – Der IV ist als Parameter des Keys zu setzen
lblb_iv = BlobMid(lblb_password, 1, 16) CryptSetKeyParam(iul_hkey, KP_IV , lblb_iv, 0)
Anschließend kann die Message entschlüsselt werden (Achtung es ist ausreichend Memory für die Operation zu reservieren)
lul_DataLen = Len(lblb_Message) lblb_Buffer = lblb_Message + Blob(Space(lul_DataLen), EncodingAnsi!) lul_BufLen = Len(lblb_Buffer) CryptDecrypt(iul_hKey, 0, True, 0, lblb_Buffer, lul_DataLen) as_message_decrypted = String(lblb_Decrypted, EncodingUTF16LE!)
Nicht zu vergessen, am Ende müssen die Handles wieder sauber freigegeben werden. Ebenfalls muss zusätzlich ein korrektes Error Handling durchgeführt werden.
Mehr zu diesem Thema: The Design of Rijndael: AES – The Advanced Encryption Standard (Information Security and Cryptography)
Ebenfalls interessant: Roadmap Powerbuilder 2017 bis 2019.
- Powerbuilder Linear Programming und Optimierung - 3. Juni 2018
- Powerbuilder Encryption – Rijndael – Win32 API - 22. April 2018
- Visitenkarte im Web – alle Schritte erklärt - 14. Mai 2017