TapHome

Šifriranje i hashevi

Funkcije skripte TapHome za šifrirane i potpisane protokole uređaja: AESENCRYPT i AESDECRYPT, HASH i HMAC s MD5 i SHA, RANDBYTES te primjer pristupnika Bosch KM200.

Funkcije šifriranja i hasheva sastavljaju ono što očekuje uređaj sa šifriranim ili potpisanim lokalnim sučeljem: šifriranje AES, hasheve MD5 i SHA, potpise HMAC i sigurne slučajne bajtove. Samo sastavljaju vrijednosti, pa rade u svakoj skripti. Sve trebaju Core 2026.1 u TapHome Next, build 40991 ili noviji (još nije u službenom izdanju). Base64, heksadecimalni tekst i kontrolni zbrojevi CRC nalaze se na stranici Kodiranje bajtova i kontrolni zbrojevi.

Primaju podatke u bajtovima: collection<uint8>, blob ili niz. Niz se koristi kao bajtovi ISO-8859-1. Za razliku od TOBYTES bez kodiranja, koji druge znakove pretvara u ?, znak izvan ISO-8859-1 ovdje je pogreška — za UTF-8 predajte TOBYTES(text, "utf-8"). Rezultat je collection<uint8>.

HASH, HMAC

HASH izračunava hash podataka u bajtovima, HMAC njihov hash s ključem (potpis).

1
2
HASH(data, algorithm)
HMAC(key, data, algorithm)
NazivOpis
dataPodaci u bajtovima čiji se hash računa.
keyKljuč funkcije HMAC, podaci u bajtovima.
algorithm"MD5", "SHA1", "SHA256" ili "SHA512", bez obzira na velika i mala slova; prihvaćaju se i "SHA-1", "SHA-256" i "SHA-512".

Vraća — collection<uint8> od 16, 20, 32 ili 64 bajta.

Napomene — HMAC kao prvi argument uzima ključ, istim redom kao hmac.new(key, msg, digest) u Pythonu.

Primjer

TOHEX(HASH("abc", "MD5"));
# Result: "900150983cd24fb0d6963f7d28e17f72"
TOHEX(HMAC("Jefe", "what do ya want for nothing?", "SHA256"));
# Result: "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"

Pogreške — 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. Poruke funkcije HMAC počinju njezinim vlastitim nazivom i navode argument.

Dostupno — Core 2026.1 u TapHome Next, build 40991 ili noviji (još nije u službenom izdanju).

AESENCRYPT, AESDECRYPT

AESENCRYPT šifrira podatke u bajtovima algoritmom AES, AESDECRYPT ih dešifrira.

1
2
AESENCRYPT(data, key, mode [, iv])
AESDECRYPT(data, key, mode [, iv])
NazivOpis
dataPodaci u bajtovima. Podaci za AESDECRYPT moraju imati duljinu koja je višekratnik od 16 bajtova.
key16, 24 ili 32 bajta: AES-128, AES-192 ili AES-256.
mode"ECB" ili "CBC", nakon čega po želji slijedi nadopuna, na primjer "CBC/PKCS7" ili "ECB/ZEROS"; bez obzira na velika i mala slova.
iv16 bajtova, obavezan za CBC. ECB ga ne uzima — izostavite argument ili predajte Null.
Nadopuna (padding)AESENCRYPTAESDECRYPT
/PKCS7 (zadano; /PKCS5, naziv iz Jave, znači isto)Dodaje nadopunu.Uklanja je.
/ZEROSPopunjava posljednji blok bajtovima 0x00; podaci koji već završavaju na granici bloka ne dobivaju ništa, prazni podaci ostaju prazni.Uklanja sve završne bajtove 0x00, i one koji pripadaju podacima — koristite je za tekst kao što je JSON.
/NONEBez nadopune; duljina podataka mora biti višekratnik od 16 bajtova.Ne uklanja ništa.

Vraća — collection<uint8>.

Napomene — Pogrešan ključ može primijetiti samo /PKCS7, i to ne uvijek; s /ZEROS i /NONE pogrešan ključ vraća pogrešne bajtove bez pogreške. Pogrešan iv u CBC iskrivljuje samo prvih 16 bajtova i nikad se ne prijavljuje.

Primjer

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"

Pogreške — AESDECRYPT - decryption failed, check the key, the iv and the padding (nadopuna /PKCS7 ne odgovara: pogrešan ključ ili podaci koji nisu šifrirani s PKCS7); 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. Svaka funkcija u poruci navodi svoj naziv.

Dostupno — Core 2026.1 u TapHome Next, build 40991 ili noviji (još nije u službenom izdanju).

RANDBYTES

RANDBYTES vraća kriptografski sigurne slučajne bajtove — za iv načina CBC, nonce ili ključ sesije.

1
RANDBYTES(count)

Vraća — collection<uint8> od count bajtova, od 1 do 2048; isto kao secrets.token_bytes(n) ili os.urandom(n) u Pythonu.

Napomene

  • RAND i RANDINT nisu sigurni i ne smiju se koristiti za ključ, iv ni nonce.
  • Varijabla sa zbirkom dodijeljena drugoj varijabli ista je zbirka, pa prije APPEND napravite COPY — inače naraste i iv.

Primjer — novi iv ispred šifriranih podataka, kako ga šalju mnogi protokoli

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"

Pogreške — RANDBYTES: count must be between 1 and 2048.

Dostupno — Core 2026.1 u TapHome Next, build 40991 ili noviji (još nije u službenom izdanju).

Primjer — pristupnik Bosch / Buderus KM200

HTTP sučelje pristupnika Bosch / Buderus KM200, koji koristi i IVT Rego 2000, onako kako ga opisuju projekti zajednice (proizvođač ga ne objavljuje). Tijelo odgovora je Base64 podataka AES-256-ECB nadopunjenih nulama, a ključ se sastoji od dva hasha MD5:

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 + ")");
END

Vidi također — Funkcije Packet parsera, Kodiranje bajtova i kontrolni zbrojevi, Tekst i zbirke.