Verschlüsselung und Hashes
Funktionen des TapHome-Skripts für verschlüsselte und signierte Geräteprotokolle: AESENCRYPT und AESDECRYPT, HASH und HMAC mit MD5 und SHA, RANDBYTES und ein Beispiel für Bosch KM200.
Die Verschlüsselungs- und Hashfunktionen bauen, was ein Gerät mit verschlüsselter oder signierter lokaler Schnittstelle erwartet: AES-Verschlüsselung, Hashes MD5 und SHA, HMAC-Signaturen und sichere Zufallsbytes. Sie bauen nur Werte, deshalb funktionieren sie in jedem Skript. Alle brauchen Core 2026.1 in TapHome Next, Build 40991 oder neuer (noch nicht im offiziellen Release). Base64, Hexadezimaltext und CRC-Prüfsummen stehen unter Byte-Kodierungen und Prüfsummen.
Sie nehmen Bytedaten an: eine collection<uint8>, einen Blob oder einen String. Ein String wird als ISO-8859-1-Bytes verwendet. Anders als bei TOBYTES ohne Kodierung, das andere Zeichen in ? umwandelt, ist ein Zeichen außerhalb von ISO-8859-1 hier ein Fehler — für UTF-8 übergeben Sie TOBYTES(text, "utf-8"). Das Ergebnis ist eine collection<uint8>.
HASH, HMAC
HASH berechnet den Hash von Bytedaten, HMAC einen Hash mit Schlüssel (eine Signatur).
| |
| Name | Beschreibung |
|---|---|
data | Bytedaten, deren Hash berechnet wird. |
key | Schlüssel von HMAC, Bytedaten. |
algorithm | "MD5", "SHA1", "SHA256" oder "SHA512", ohne Beachtung der Groß- und Kleinschreibung; "SHA-1", "SHA-256" und "SHA-512" werden ebenfalls akzeptiert. |
Rückgabewert — collection<uint8> mit 16, 20, 32 oder 64 Bytes.
Hinweise — HMAC nimmt den Schlüssel zuerst, in derselben Reihenfolge wie hmac.new(key, msg, digest) in Python.
Beispiel
TOHEX(HASH("abc", "MD5"));
# Result: "900150983cd24fb0d6963f7d28e17f72"
TOHEX(HMAC("Jefe", "what do ya want for nothing?", "SHA256"));
# Result: "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"Fehler — HASH Unknown algorithm. Valid values are ‘MD5’, ‘SHA1’, ‘SHA256’, ‘SHA512’; HASH - data contains characters outside ISO-8859-1, convert the text with TOBYTES(text, “utf-8”); HASH - data must be a uint8 collection, a blob or a string. Die Meldungen von HMAC beginnen mit ihrem eigenen Namen und nennen das Argument.
Verfügbar — Core 2026.1 in TapHome Next, Build 40991 oder neuer (noch nicht im offiziellen Release).
AESENCRYPT, AESDECRYPT
AESENCRYPT verschlüsselt Bytedaten mit AES, AESDECRYPT entschlüsselt sie.
| |
| Name | Beschreibung |
|---|---|
data | Bytedaten. Daten für AESDECRYPT müssen eine Länge haben, die ein Vielfaches von 16 Bytes ist. |
key | 16, 24 oder 32 Bytes: AES-128, AES-192 oder AES-256. |
mode | "ECB" oder "CBC", optional gefolgt vom Padding, zum Beispiel "CBC/PKCS7" oder "ECB/ZEROS"; ohne Beachtung der Groß- und Kleinschreibung. |
iv | 16 Bytes, von CBC verlangt. ECB nimmt keinen — lassen Sie das Argument weg oder übergeben Sie Null. |
| Padding | AESENCRYPT | AESDECRYPT |
|---|---|---|
/PKCS7 (Standard; /PKCS5, der Java-Name, bedeutet dasselbe) | Fügt das Padding hinzu. | Entfernt es. |
/ZEROS | Füllt den letzten Block mit Bytes 0x00; Daten, die bereits an einer Blockgrenze enden, bekommen keine, leere Daten bleiben leer. | Entfernt alle abschließenden Bytes 0x00, auch die, die zu den Daten gehören — verwenden Sie es für Text wie JSON. |
/NONE | Kein Padding; die Datenlänge muss ein Vielfaches von 16 Bytes sein. | Entfernt nichts. |
Rückgabewert — collection<uint8>.
Hinweise — Nur /PKCS7 kann einen falschen Schlüssel bemerken, und auch das nicht immer; mit /ZEROS und /NONE liefert ein falscher Schlüssel falsche Bytes ohne Fehler. Ein falscher iv in CBC verfälscht nur die ersten 16 Bytes und wird nie gemeldet.
Beispiel
VAR key := BYTECOLLECTION("2b7e151628aed2a6abf7158809cf4f3c");
VAR iv := BYTECOLLECTION("000102030405060708090a0b0c0d0e0f");
VAR secret := AESENCRYPT("Hello World", key, "CBC", iv);
TOSTRING(AESDECRYPT(secret, key, "CBC", iv));
# Result: "Hello World"Fehler — AESDECRYPT - decryption failed, check the key, the iv and the padding (das Padding /PKCS7 passt nicht: ein falscher Schlüssel oder Daten, die nicht mit PKCS7 verschlüsselt wurden); AESENCRYPT - key must be 16, 24 or 32 bytes long (AES-128, AES-192, AES-256), it is N; AESENCRYPT - CBC mode needs a 16-byte iv, it is N; AESENCRYPT - ECB mode does not use an iv, leave the argument out; AESENCRYPT Unknown mode. Valid values are ‘ECB’, ‘CBC’, optionally followed by ‘/PKCS7’ (or ‘/PKCS5’), ‘/ZEROS’ or ‘/NONE’; AESENCRYPT - with padding NONE the data length must be a multiple of 16 bytes, it is N; AESDECRYPT - encrypted data length must be a multiple of 16 bytes, it is N. Jede Funktion nennt in der Meldung ihren eigenen Namen.
Verfügbar — Core 2026.1 in TapHome Next, Build 40991 oder neuer (noch nicht im offiziellen Release).
RANDBYTES
RANDBYTES liefert kryptografisch sichere Zufallsbytes — für einen iv von CBC, eine Nonce oder einen Sitzungsschlüssel.
| |
Rückgabewert — collection<uint8> mit count Bytes, 1 bis 2048; dasselbe wie secrets.token_bytes(n) oder os.urandom(n) in Python.
Hinweise
- RAND und RANDINT sind nicht sicher und dürfen nicht für einen Schlüssel, einen
ivoder eine Nonce verwendet werden. - Eine Sammlungsvariable, die einer anderen Variablen zugewiesen wird, ist dieselbe Sammlung; nehmen Sie daher eine
COPY, bevor Sie mitAPPENDetwas anhängen — sonst wächst auch deriv.
Beispiel — ein neuer iv vor den verschlüsselten Daten, wie ihn viele Protokolle senden
VAR key := FROMHEX("2b7e151628aed2a6abf7158809cf4f3c");
VAR iv := RANDBYTES(16);
VAR body := COPY(iv);
APPEND(body, AESENCRYPT("Hello World", key, "CBC", iv));
TOSTRING(AESDECRYPT(COPY(body, 16), key, "CBC", COPY(body, 0, 16)));
# Result: "Hello World"Fehler — RANDBYTES: count must be between 1 and 2048.
Verfügbar — Core 2026.1 in TapHome Next, Build 40991 oder neuer (noch nicht im offiziellen Release).
Beispiel — Gateway Bosch / Buderus KM200
Die HTTP-Schnittstelle eines Gateways Bosch / Buderus KM200, das auch IVT Rego 2000 verwendet, so wie Community-Projekte sie beschreiben (der Hersteller veröffentlicht sie nicht). Der Body ist Base64 von AES-256-ECB-Daten, die mit Nullen aufgefüllt sind, und der Schlüssel besteht aus zwei MD5-Hashes:
VAR salt := BYTECOLLECTION("00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); # 32-byte vendor salt
VAR k1 := TOBYTES(REPLACE("xxxx-xxxx-xxxx-xxxx", "-", "")); # gateway password
APPEND(k1, salt);
VAR k2 := COPY(salt);
APPEND(k2, TOBYTES("my private password"));
VAR key := HASH(k1, "MD5");
APPEND(key, HASH(k2, "MD5")); # 32 bytes = AES-256
VAR r := SENDHTTPREQUEST("/system/healthStatus", "GET", "", "User-Agent: TeleHeater/2.2.3");
# value = a module variable that keeps the result
IF r.IsSuccess
value := PARSEJSON(TOSTRING(AESDECRYPT(FROMBASE64(r.Content), key, "ECB/ZEROS"), "utf-8"), "value");
ELSE
ADDERROR(r.StatusCode + " (" + r.ReasonPhrase + ")");
ENDSiehe auch — Packet-Parser-Funktionen, Byte-Kodierungen und Prüfsummen, Text und Sammlungen.