AES Keyaenderung aus fhem

Begonnen von mgernoth, 03 Juni 2015, 14:03:35

Vorheriges Thema - Nächstes Thema

mgernoth

Hallo,

da es bisher nicht moeglich war, den AES-Schluessel eines Geraetes via fhem auszutauschen, habe ich einen kleinen Perl-Schnipsel gebastelt, der dies erledigt (auch als Anhang):


#set Steckdose_Test sign on
#{set_hmKey("Steckdose_Test")}
# set_hmKey(device)
#  KeyIdx: 0 - default, 1 - hmKey, 2 - hmKey2, ...
sub set_hmKey(@)
{
        my $device = shift;
        #my $newKeyIdx = shift;

        my $oldKeyIdx = ReadingsVal($device, "aesKeyNbr", "00");
        if ((!defined($oldKeyIdx)) || ($oldKeyIdx eq "")) {
                Log(1, "Can't get old keyindex!");
                return 0;
        }

        #?Same as for Key-updates?
        $oldKeyIdx /= 2;

        my $hmId = CUL_HM_name2Id($device, ());
        if ((!defined($hmId)) || ($hmId eq "000000")) {
                Log(1, "Can't get id for device!");
                return 0;
        }

        my $hash = CUL_HM_name2Hash($device);
        if (!defined($hash)) {
                Log(1, "Can't find hash for device!");
                return 0;
        }

        my $ioId = CUL_HM_IoId($hash);
        if ((!defined($ioId)) || ($ioId eq "000000")) {
                Log(1, "Can't get central hmid!");
                return 0;
        }

        if (defined($hash->{chanNo})) {
                Log(1, "Can't update key of a channel!");
                return 0;
        }

        Log(1, "Updating AES key of ${device} (${hmId}) from old index ${oldKeyIdx}, ioId ${ioId}");

        # Key-updates are split into two packets as key is too long for one */
        my $cmd1 = sprintf("++A004%s%s01%02X", $ioId, $hmId, $oldKeyIdx * 2);
        my $cmd2 = sprintf("++A004%s%s01%02X", $ioId, $hmId, ($oldKeyIdx * 2) + 1);
        Log(1, "set ${device} raw ${cmd1}");
        fhem "set ${device} raw ${cmd1}";
        Log(1, "set ${device} raw ${cmd2}");
        fhem "set ${device} raw ${cmd2}";

        # Should send init-message for new key index to include in challenges
        #my $init = sprintf("+%s,01,%02X,00", $hmId, $newKeyIdx);
        #Log(1, "sending init for ${device}: ${init}");
        #IOWrite($hash, "cmd", "${init}");
}


Mit diesem Schnipsel wird der aktuelle Schluessel eines Geraetes auf den neuesten dem HM-CFG-LAN (oder HM-CFG-USB) bekannten Schluessel aktualisiert. Das Reading aesKeyNbr ist nicht immer vorhanden, weswegen hier von 00 (default-key) ausgegangen wird. Dummerweise wird dieses Reading bei Fernbedienung nicht autmoatisch aktualisiert, weswegen hier eigentlich nur die Aenderung des Default-Keys auf den ersten eingestellten Key moeglich ist.

Benutzt werden kann das ganze z.B. so:


fhem> attr HMCFGUSB hmKey geheim (diesen Schluessel aufbewahren!)
...
fhem> inform timer
fhem> set Steckdose_Test sign on
2015-06-03 13:55:55 CUL_HM Steckdose_Test R-sign: set_on

fhem> set Steckdose_Test off
2015-06-03 13:56:11 CUL_HM Steckdose_Test set_off
2015-06-03 13:56:11 CUL_HM Steckdose_Test aesKeyNbr: 00
...

fhem> {set_hmKey("Steckdose_Test")}
2015-06-03 13:56:32 CUL_HM Steckdose_Test aesKeyNbr: 00
2015-06-03 13:56:33 CUL_HM Steckdose_Test aesKeyNbr: 00

fhem> set Steckdose_Test off
2015-06-03 13:56:39 CUL_HM Steckdose_Test set_off
2015-06-03 13:56:39 CUL_HM Steckdose_Test aesKeyNbr: 02
...



Die aesKeyNbr scheint den doppelten Wert des aktuellen Key-Index zu enthalten, da der Schluessel in zwei Schritten (mit eigenen Indizes) zum Geraet uebertragen wird und hier wohl direkt der interne Index benutzt wird.

Evtl. kann man das benutzerfreundlicher in fhem direkt einbauen um ein Schluesselupdate von einem Geraet direkt aus anzustossen. Vorher muss aber noch das Problem geloest werden, den aktuellen Schluesselindex einer Fernbedienung abzufragen.

Gruss
  Michael

Wuppi68

cooooooooool !!!!!!!!!!!!!!!!!!!!!!!!!!

werde  mir das mal zu Hause in Ruhe anschauen ... wenn es dann klappt, kann ich wenigstens direkt aus FHEM die Schlüssel setzen und die Windows SW vergessen :-)

Wie kann ich eigentlich die Schlüsselhistory auch in den Devices löschen?

Reicht da ein Reset auf Werksenstellungen um danach mit dem letzten bekannten AES Schlüssel das Teil neu zu setzen?

so nach dem Motto

set aes_key(lkshefhsdghakhaieuranbvkaehrviu)
reset auf Werkseinstellung
set aes_key(lkshefhsdghakhaieuranbvkaehrviu)


und danach die ganzen Keys auch im HMLAN wieder zu entfernen?
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

Deudi

Wow, genau sowas suche ich. Bisher war ich mit Homematic im Wohngebiet alleine unterwegs, nun sind in der Nachbarschaft die ersten Rolloaktoren aufgetaucht. Daher möchte ich kritische Steuerungen auf signing umstellen. Bisher war ich aber zu faul alle Geräte am Windows Konfigurationsprogramm anzulernen, damit der Schlüssel übertragen wird.

Habe ich das richtig verstanden, dass ich mir das mit dem Perl-Code sparen kann?
Gigabyte Brix, Ubuntu 16.04.3 LTS, Homematic, Z-Wave, EnOcean, Shelly@MQTT, SIGNALduino, JeeLink DAVIS-Sketch

mgernoth

Hallo,

Zitat von: Wuppi68 am 03 Juni 2015, 15:06:03
Wie kann ich eigentlich die Schlüsselhistory auch in den Devices löschen?
Reicht da ein Reset auf Werksenstellungen um danach mit dem letzten bekannten AES Schlüssel das Teil neu zu setzen?

So ähnlich:

  • Reset aller Geräte über fhem
  • Löschen der Schlüssel aus fhem, Neustart
  • Neustart des Interfaces
  • Hinzufügen des neuen Schlüssels in fhem
  • Wiederanlernen aller Geräte (hmPairSerial/hmPairForSec)
  • Signierung für Gerät aktivieren und Schlüssel übertragen

Man kann immer nur "neuere" Schlüssel(-indizes) direkt an ein Gerät übertragen, für ältere muss man das Gerät resetten...

Zitat von: Deudi am 03 Juni 2015, 15:12:00
Habe ich das richtig verstanden, dass ich mir das mit dem Perl-Code sparen kann?

Yep, ganz genau. :-)

Gruß
  Michael

Ralli

Hallo Michael,

tolle Idee. Mal schauen, was Martin dazu sagt ;).
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

Benni

Zitat von: Ralli am 03 Juni 2015, 16:15:58
Mal schauen, was Martin dazu sagt ;).

Coole Sache!  8)
Wenn das funktioniert gehört es unbedingt in HMLAN direkt implementiert  ;D

mgernoth

#6
Hallo,

bzgl. AES-Key moechte ich noch diesen Beitrag (2. Beitrag des Threads, Pastebin) aus dem Homegear-Forum verlinken: https://forum.homegear.eu/viewtopic.php?t=217#p1485

Gruss
  Michael

Damu

#7
Hallo

Bei mir wird Key NR. 02 angezeigt.
Ich lerne immer alles zuerst mit der HM-Software an.
Ist es mit dem Modul also möglich diesen Key beim anmelden automatisch auf das Device zu bringen?
So wie es die HM-Software macht.

Wuppi68

laut dem Forum verlinkten Beitrag ist der default AES Key

A4E375C6B09FD185F27C4E96FC273AE4
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

mgernoth

#9
Hallo,

Ja, der Schlüssel stimmt. Damit habe den Schlüsselaustausch auf meinen eigenen Schlüssel entschlüsseln können...
Noch ein Grund, nicht diesen Key zu verwenden, sondern so schnell wie möglich einen eigenen Schlüssel zu setzen.

Mit Kenntnis dieses Default-Keys muss man aber auch sehen, dass nun ein potentieller Angreifer auch an einen selbst gesetzten Schlüssel kommen kann, wenn er die Schlüsselaustauschnachrichten eines Geräts mitschneidet (wenn z.B. ein neues Gerät angelernt wird und der eigene Schlüssel durch CCU/Windows-SW übertragen wird oder halt das set_hmKey() benutzt wird).

Gruß
  Michael

martinp876

sollte implementiert werden.
Zum einen sollt es in die VCCU implementiert werden, da alle HMLAN einer vccu die gleichen Keys haben sollten/müssen (steht noch bevor).


Inhaltlich verstehe ich es nicht.
Du sendest 2 mal das gleiche Kommando - einmal mit key "x" dann mit "x+1".
Warum? Wo ist es her?
Was passiert ist, dass HMLAN eine Message an das Device schickt mit einem Key der wohl kodiert ist. Somit macht sniffen wenig sinn, da der Inhalt nicht konstant ist.
HMLAN bekommt eine Nummer und sendet eine eigene Message an das Device.
Ich habe probiert dass ich 00 oder 01 schicken kann. 0a ging dann auch wieder.

Was also macht dein Code? Setzt er das Device auf den Key 00, der im HMLAN gespeichert ist?

Ich werde es gerne implementieren - so ist es aber unklar. Du gibst auch keinen Key an. Warum glaubt du braucht man den alten key? den neuen hast du nicht spezifiziert.


mgernoth

Hallo Martin,

Zitat von: martinp876 am 04 Juni 2015, 20:06:58
sollte implementiert werden.

:-)

Zitat
Zum einen sollt es in die VCCU implementiert werden, da alle HMLAN einer vccu die gleichen Keys haben sollten/müssen (steht noch bevor).

Ja, das würde die Sache deutlich verschönern :-)

Zitat
Inhaltlich verstehe ich es nicht.
Du sendest 2 mal das gleiche Kommando - einmal mit key "x" dann mit "x+1".
Warum? Wo ist es her?

Ja, der neue 16-byte Schlüssel wird in zwei Nachrichten an das Gerät geschickt, wobei x/2 der alte Keyindex des dem Gerät bekannten Schlüssels ist. Damit verschlüsselt der HMLAN dann die neuen Schlüsselhälften mit dem alten Schlüssel. Der Index des neuen Schlüssels muss hier nirgends angegeben werden.

Zitat
Was passiert ist, dass HMLAN eine Message an das Device schickt mit einem Key der wohl kodiert ist. Somit macht sniffen wenig sinn, da der Inhalt nicht konstant ist.

Die Verschlüsselung auf diesem Weg ist sehr einfach, weshalb man diese Nachrichten problemlos entschlüsseln kann.
Hier mal ein Beispiel, Steckdose_Test (1ED017) hat noch den Default-Key, der aktuelle Key (0x0000000000000000) hat den im HMLAN den Index 1, in den Geräten die Indizes 2+3:


fhem> {set_hmKey("Steckdose_Test")}



2015-06-04 20:51:09.279246: LAN > SBFE9A3AB,00,00000000,01,BFE9A3AB,02A00468EA131ED0170100
2015-06-04 20:51:09.484822: LAN < E1ED017,0100,2DAE615E,FF,FFD7,02A0021ED01768EA13045327F2C6384F00
2015-06-04 20:51:09.740836: LAN < RBFE9A3AB,0021,2DAE6163,00,FFD7,0280021ED01768EA1300A94A083A

2015-06-04 20:51:09.843540: LAN > SBFE9A57F,00,00000000,01,BFE9A57F,03A00468EA131ED0170101
2015-06-04 20:51:10.156846: LAN < E1ED017,0100,2DAE63F0,FF,FFD7,03A0021ED01768EA1304C329B77E85AD00
2015-06-04 20:51:10.380863: LAN < RBFE9A57F,0021,2DAE63F5,00,FFD7,0380021ED01768EA13006F82412D


In der Luft passiert folgendes, AES-Nachrichten habe ich entschlüsselt:


A1902A00468EA131ED01701020000000000000000E87E7E296FA5
(A1102A0021ED01768EA13045327F2C6384F00) sig. req. mit altem Key
(A1902A00368EA131ED0174465949899CD52D8C9ADAABEDAC4A32A) sig. resp.
A0E0280021ED01768EA1300A94A083A

A1903A00468EA131ED0170103000000000000000096F77E296FA5
(A1103A0021ED01768EA1304C329B77E85AD00) sig. req. mit altem Key
(A1903A00368EA131ED01744817E0629603797C13375ECDE030A9A) sig. resp.
A0E0380021ED01768EA13006F82412D


Hier sieht man, dass in den Nachrichten an das Gerät die neuen Zielindizes angegeben werden, obwohl diese in der Nachricht an den HMLAN nicht vorkamen (0x00 -> 0x02, 0x01 -> 0x03). Das hinter dem Schlüsselteil scheint jeweils eine Checksumme zu sein.

Zitat
HMLAN bekommt eine Nummer und sendet eine eigene Message an das Device.
Ich habe probiert dass ich 00 oder 01 schicken kann. 0a ging dann auch wieder.

Ja, Du hast wahrscheinlich keinen eigenen Schlüssel gesetzt und damit nur im Index 0 den Default-Key, weswegen 0 und 1 funktionieren. Wenn Du noch einen Schlüssel in Index 1 hättest, dann würden auch 2 und 3 funktionieren. Und ich nehme an, dass der HMLAN nur 5 Indizes kann, weswegen 0xa wieder 0x0 entspricht.

Zitat
Was also macht dein Code? Setzt er das Device auf den Key 00, der im HMLAN gespeichert ist?

Nein, er setzt den aktuelleren dem HMLAN bekannten Schlüssel auf dem Gerät und verschlüsselt ihn mit dem älteren.

Zitat
Ich werde es gerne implementieren - so ist es aber unklar. Du gibst auch keinen Key an. Warum glaubt du braucht man den alten key? den neuen hast du nicht spezifiziert.

Als neuen nimmt der HMLAN AFAIK den nächsten ihm bekannten Schlüssel (also Index+1).
Falls man also 2 Schlüssel in Index 1 und 2 konfiguriert hat:

1. Austausch mit Def.Key an Index 0:
An HMLAN: 0100 / 0101
Von HMLAN an Gerät: 0102 / 0103

Danach den Austausch nochmal anschmeissen, diesmal mit dem Schlüssel an Index 1:
An HMLAN: 0102 / 0103
Von HMLAN an Gerät: 0104 / 0105

So wird sichergestellt, dass alle Geräte alle dem System bekannten Schlüssel kennen.

Achja, Code um die AES-Nachrichten zu dekodieren (nur die letzten 16 Byte) findest Du hier: http://forum.fhem.de/index.php/topic,20121.msg136802.html#msg136802

Wenn man da in @keys den aus http://forum.fhem.de/index.php/topic,37787.msg300613.html#msg300613 bekannten Defaultkey einsetzt, kann man damit auch die ersten Schlüsselaustauschnachrichten dekodieren.

Gruß
  Michael

frank

moin,

ich habe so das gefühl, dass es in naher zukunft beiträge über "key-phishing" geben wird. irgendwie muss dann ja wohl nur ein weg gefunden werden, einen schlüsseltausch zu forcieren, wenn man nicht ewig vor der tür auf einen freiwilligen schlüsseltausch warten will. eventuell mit einem eingeschleussten device. oder ist der hmlan vielleicht so "gesprächig", dass er sogar, mit den entsprechenden funksprüchen konfrontiert, von sich aus die schlüssel tauschen würde?

wenn ich eine keymatic (oder andere sicherheits relevante devices) hätte, müsste ich jetzt wohl sämtliche schlüssel aller devices im "abhörsicheren" keller erneuern, um auszuschliessen, dass mein nachbar seine alten logs nach meinen schlüsselübergaben durchforstet.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

hm - muss ich einmal testen.

mein HMLAN hat 3 keys (ich nutze eigentlich keine - nur so zum testen).

   hmKey       01:dd4b21e9ef71e1291183a46b913ae6f2
   hmKey2     02:834B23152C250AADD5C0C378432B228A
   hmKey3     03:289dff07669d7a23de0ef88d2f7129e7

wenn ich es setze kommt:
HMLAN_Send:  iohl1 stat:  00   m:45 A004 1743BF 34248C 0100
sniff Parse: iocu1            19 45 A004 1743BF 34248C 848063A38C05A406D70B7A8F06938884
sniff Parse: iocu1            11 45 A002 34248C 1743BF 04E4527F31FE5400
HMLAN_Parse: iohl1 stat:0100   m:45 A002 34248C 1743BF 04E4527F31FE5400
sniff Parse: iocu1            19 45 A003 1743BF 34248C 1A784B6553217F2A649F3A75A36B7706
sniff Parse: iocu1            0E 45 8002 34248C 1743BF 00ED0B52FB
HMLAN_Parse: iohl1 stat:0021   m:45 8002 34248C 1743BF 00ED0B52FB

gesendet wird also der Key kodiert. In der Luft kann ich den Key nicht erkennen. Du hast sicher recht, dass der neue key  mit dem alten verschlüsselt wird. Man kann den Key nur ändern, wann man den alten kennt.

Da ich 3 keys im HMLAN gesetzt haben wäre dies schon möglich.
habe gerade einmal probiert, 4 keys zu setzen - dann rebootet mein HMLAN. hmmm - rund ist es noch nicht aus meiner sicht.
Unklar ist schon einmal woher HMLAN weiss, welches device welchen key nutzt. Könnte an einer vorangegangenen Antwort festgemacht sein.

mgernoth

Zitat von: martinp876 am 06 Juni 2015, 21:06:09

wenn ich es setze kommt:
HMLAN_Send:  iohl1 stat:  00   m:45 A004 1743BF 34248C 0100
sniff Parse: iocu1            19 45 A004 1743BF 34248C 848063A38C05A406D70B7A8F06938884
...

gesendet wird also der Key kodiert. In der Luft kann ich den Key nicht erkennen. Du hast sicher recht, dass der neue key  mit dem alten verschlüsselt wird. Man kann den Key nur ändern, wann man den alten kennt.

Ja, der ist in diesem Fall mit dem Default-Key verschlüsselt. Entschlüsselt steht da:

01 02 DD 4B 21 E9 EF 71 E1 29 6F F9 7E 29 6F A5


Zitat
Da ich 3 keys im HMLAN gesetzt haben wäre dies schon möglich.
habe gerade einmal probiert, 4 keys zu setzen - dann rebootet mein HMLAN. hmmm - rund ist es noch nicht aus meiner sicht.

Ja, auf das Y-Kommando werden nur 3 Benutzerslots ausgegeben. der erste ist immer mit dem Keyindex 0 (default-Key) belegt.

Zitat
Unklar ist schon einmal woher HMLAN weiss, welches device welchen key nutzt. Könnte an einer vorangegangenen Antwort festgemacht sein.

Ich denke, dass das der 3. Parameter in der +-Nachricht ist, der nach dem aesCommReq-Flag.

Gruß
  Michael