Hallo Forum, ich versuche mit Java, Daten aus Geräten (Zähler im OMS (Open Metering System)) zu entschlüsseln. Verschlüsselt sind die Daten mit *AES 128 CBC FIPS 197*. Auf der Webseite https://www.miller-alex.de/WMbus ist die Entschlüsselung zum Testen implementiert. Auf dieser Seite lassen sich meine Daten entschlüsseln. Also, habe ich den richtigen AES Schlüssel für die Daten und ich sehe u.a. einen IV. Mein Implementierungsversuch findet man bei https://github.com/bitkorn/aes-java/tree/main/de/bitkorn/aes. Es gibt eine `Main.java` und eine `AES.java`. Die Entschlüsselung ist in der `AES.java`. Implementierungen im Netz (und ChatGPT) machen es genau wie ich. Leider gibt mir meine Implementierung nur unleserliche Zeichen zurück. Bei AES 128 CBC FIPS 197 werden mehrere Entschlüsselungs-Runden gemacht. Und der IV für den nächsten Block wird aus dem vorigen Block erzeugt usw. usw.. Das sollte doch die Java Funktion (`javax.crypto.Cipher() => doFinal(byte[] input)`) übernehmen, oder? Oder, muss ich die Runden implementieren? Wie entschlüsselt man solche Daten? Kann mir jemand weiter helfen? Wo habe ich den Denkfehler?
Um die Korrektheit einer Ver-/Entschlüsselungs-Software nachzuweisen, benutzt man üblicherweise Testdaten. Ich bin mir sehr sicher, daß der FIPS 197 Standard derartige Testdaten enthält.
Axel S. schrieb: > Um die Korrektheit einer Ver-/Entschlüsselungs-Software nachzuweisen, > benutzt man üblicherweise Testdaten. Ich bin mir sehr sicher, daß der > FIPS 197 Standard derartige Testdaten enthält. Hallo Axel, Testdaten habe ich bereits. Wie oben geschrieben, habe ich Daten inklusive dem AES Schlüssel, die mit anderer Software (https://www.miller-alex.de/WMbus) entschlüsselt werden kann.
Jetzt findet man in dem Repository einen Datenbank Dump mit Testdaten. Z.B. für die Device ID 00945301 (AES Key: 9876543210FEDCBA9876543210FEDCBA) wären die ersten verschlüsselten Daten: 5E44A8340153940081087A034050050CBE58A7DBF052E98AC2122D5C7A74C4F6A8D9EA3A 5BC709FA67012FB8B4CF5DB7EA294014FFD4F0CCEC210D78587C10F92648ACFF6EFF8A7E 1301DD10923E9DA14F823C1B51C0ED5ABDB9DD9AD19BFBFF Mit diesen Daten kann die Seite https://www.miller-alex.de/WMbus umgehen. Mein Code gibt Folgendes aus: �M���=1w�S�q�u;�lV$l�*��z��ޚQ ������ O{`_=��;��uǼhu"%�K1z�ͥ���]ў��-b�HV6_A#7��4�L`�a��w� �]Q��R݁����Y�Ca�o]���t�]ں���)�-Ǐ������D�����3�8C��y��F�g�2��������e Wie wird die Java Funktion (`javax.crypto.Cipher() => doFinal(byte[] input)`) für AES 128 CBC richtig angewendet?
Torsten schrieb: > Mein Code gibt Folgendes aus: > �M���=1w�S�q�u;�lV$l�*��z��ޚQ > ������ > O{`_=��;��uǼhu"%�K1z�ͥ���]ў��-b�HV6_A#7��4�L`�a��w� > �]Q��R݁����Y�Ca�o]���t�]ں���)�-Ǐ������D�����3�8C��y��F�g�2��������e Wenn es wirklich Wireless MBus ist, das du entschlüsseln willst, dann solltest du das Ergebnis als HEX darstellen und nicht als ASCII-Zeichen.
Ich sehe momentan nicht wie sich Deine Daten auf https://www.miller-alex.de/WMbus entschlüsseln lassen. Da wird bei mir nur der unverschlüsselte Header der Daten angezeigt. Wenn die Entschlüsselung klappt sollten dort auch die entschlüsselten Daten stehen (hinter "DECRYPTED", so wie mit dem Default-Beispiel), das passiert bei Deinen Daten nicht. Entweder stimmen Deine Daten nicht (warum steht z.B. ein 0xFF am Ende?) oder der Schlüssel ist falsch. Nachtrag: Soll 9876543210FEDCBA9876543210FEDCBA tatsächlich ein individueller Schlüssel für den Smart Meter sein?
:
Bearbeitet durch User
[Bin kein Java Programmierer - kenne die Sprache nur grob und die Libraries gar nicht.] Ich vermute mal, dass die Cryptoroutinen bereits das Chaining machen (cipherType = "AES/CBC/NoPadding"). Allerdings bezweifel ich, dass aesKey.getBytes(StandardCharsets.UTF_8) korrekt sein kann: entweder ist der Key ein Hex-String, dann muß der nach Binary konvertiert werden, oder er ist bereits Binary, dann ist das UTF_8 verkehrt.
Sebastian R. schrieb: > Wenn es wirklich Wireless MBus ist, das du entschlüsseln willst, dann > solltest du das Ergebnis als HEX darstellen und nicht als ASCII-Zeichen. So wie du es schreibst, klingt es lustig, weil ich es als Hex mit Garantie nicht lesen kann. Dieter S. schrieb: > Ich sehe momentan nicht wie sich Deine Daten auf > https://www.miller-alex.de/WMbus entschlüsseln lassen. > ... Mist, du hast Recht. Ich habe andere Daten, die auf der Seite einen Error produzieren. Da war ich mit diesen Daten wohl etwas schnell mit positivem Denken. Individuell sind die AES Keys in meiner Datenbank alle nicht. Manche bestehen nur aus lauter großen 'F'. Es scheint ein riesen Datenmüll Problem zu sein :( Foobar schrieb: > Ich vermute mal, dass die Cryptoroutinen bereits das Chaining machen > (cipherType = "AES/CBC/NoPadding"). > > Allerdings bezweifel ich, dass aesKey.getBytes(StandardCharsets.UTF_8) > korrekt sein kann: entweder ist der Key ein Hex-String, dann muß der > nach Binary konvertiert werden, oder er ist bereits Binary, dann ist das > UTF_8 verkehrt. Deine Aussage mit dem Chaining versüßt mir den Tag. U.a. habe ich auch in C++ die AES Implementierung mit diesen Chainings und XORS aus verschiedenen Quellen studiert. Darum bin ich schon sehr zufrieden, wenn die Funktion das Chaining etc schon macht. Zu deiner anderen Aussage: `SecretKeySpec` hat nur Konstruktoren die den Key als byte[] erwarten. Und da braucht es eine Codierung. Die Funktion ohne Codierung aufrufen bringt den gleiche Müll raus. ------- Zusammengefasst scheinen die Daten Müll zu sein. Darum suche ich jetzt mittels der Webseite https://www.miller-alex.de/WMbus bei mir nach Daten die sich entschlüsseln lassen.
Torsten schrieb: > > Zusammengefasst scheinen die Daten Müll zu sein. Darum suche ich jetzt > mittels der Webseite https://www.miller-alex.de/WMbus bei mir nach Daten > die sich entschlüsseln lassen. Zum Testen Deiner AES Implementierung kannst Du ja das Default-Beispiel von der Webseite nehmen.
1 | Key |
2 | F8B24F12F9D113F680BEE765FDE67EC0 |
3 | |
4 | IV |
5 | 496A0392631400075050505050505050 |
6 | |
7 | Encrypted |
8 | 98A78E0D71AA6358EEBD0B20BFDF99ED |
9 | A2D22FA25314F3F1B84470898E495303 |
10 | 923770BA8DDA97C964F0EA6CE24F5650 |
11 | C0A6CDF3DE37DE33FBFBEBACE4009BB0 |
12 | D8EBA2CBE80433FF131328206020B1BF |
13 | |
14 | Dercrypted |
15 | 2F2F0C1329730600026C942182046C81 |
16 | 218C0413754406008D0493132CFBFE12 |
17 | 44005141007035007733007549001636 |
18 | 00735600915500955700315700284200 |
19 | 18470061390056420002FD1700002F2F |
Der "Encrypted" Teil ist bereits ohne den Header. Das funktioniert mit AES-CBC (No Padding), muss aber noch von Hexadezimal in die entsprechenden Bytes umgewandelt werden.
Torsten schrieb: > So wie du es schreibst, klingt es lustig, weil ich es als Hex mit > Garantie nicht lesen kann. Die Telegramme sind aber nicht menschenlesbar. Bei der Entschlüsselung wird nicht "Die Temperatur beträgt 23,7°C" herauskommen, sondern eben ein Haufen Bytes, die noch durch einen Parser menschenlesbar gemacht werden müssen.
Jetzt habe ich auch eigene Daten, die sich entschlüsseln lassen :) Key: B8AA9688DDD6528E86D8EEB45F866908 RAW: 7644C5250301101055087203011010C52555084D0060053F1EC0BB524BEEA88234B44D7D 9F7888010E24593CAD21E27CE9E15AD82E215235AB08041AC46F6E19B8BF8A0BCA66840E 3B7288699BDB9F7E81A85F3152E76161AEFEFCBF9F8F5A067161DBDF48D9EEE7091DEAA6 C7D78CEC1E5831E3372A98FF Die Seite miller-alex.de/WMbus sagt der IV ist C5250301101055084D4D4D4D4D4D4D4D. Hier ist bei mir ein Problem mit dem Java Cipher: ``` IV: C5250301101055084D4D4D4D4D4D4D4D java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long at java.base/com.sun.crypto.provider.CipherCore.init(CipherCore.java:525) ``` Der IV ist richtig. Sonst würde miller-alex.de/WMbus ja meckern. Lasse ich beim IV die letzte Hälfte weg, dann bleibt noch C525030110105508. Da meckert Java nicht, ist aber nicht der richtige IV. Irgendjemand da der schon mal mit Java AES 128 CBC entschlüsselt hat?
Die neuen Daten lassen sich auf jeden Fall korrekt entschlüsseln:
1 | Key |
2 | B8AA9688DDD6528E86D8EEB45F866908 |
3 | |
4 | IV |
5 | C5250301101055084D4D4D4D4D4D4D4D |
6 | |
7 | Encrypted |
8 | 3F1EC0BB524BEEA88234B44D7D9F7888 |
9 | 010E24593CAD21E27CE9E15AD82E2152 |
10 | 35AB08041AC46F6E19B8BF8A0BCA6684 |
11 | 0E3B7288699BDB9F7E81A85F3152E761 |
12 | 61AEFEFCBF9F8F5A067161DBDF48D9EE |
13 | E7091DEAA6C7D78CEC1E5831E3372A98 |
14 | |
15 | Dercrypted |
16 | 2F2F0B6E530400426EB80182016E8401 |
17 | C2016E320182026ED800C2026E5E0082 |
18 | 036E8D01C2036E8D0182046E7401C204 |
19 | 6E740182056E4501C2056E430182066E |
20 | 4301C2066E430182076E4301C2076E43 |
21 | 0182086EB800C2086E340002FD170000 |
Du mußt in Deinem Java Code die richtige Repräsentation der Bytes beachten, z.B. der Hex-String "ABCD" ist etwas anderes als die beiden Bytes 0xAB 0xCD.
Dieter S. schrieb: > Du mußt in Deinem Java Code die richtige Repräsentation der Bytes > beachten, z.B. der Hex-String "ABCD" ist etwas anderes als die beiden > Bytes 0xAB 0xCD. Dass ich da irgendwo Murks mache, hatte ich schon mal vermutet. Mein IV ist ein Hex String den ich per Java Funktion in Bytes wandle und dem IvParameterSpec Konstruktor übergebe. Sollte OK sein. Mit dem AES Key verfahre ich gleich: hex String nach Bytes für den Konstruktor. Mein decrypteter Hex String ist ein anderer als der, der bei miller-alex.de/WMbus raus kommt. Ist also Müll. Kann man ja kaum was falsch machen. Mist, Mist, Mist. Vielleicht versuche ich es in einer Kirche ;)
Ich verwende normalerweise kein Java. Main.java ist nur mal schnell zusammengestrickt und soll nicht als Referenz für guten Stil dienen, liefert aber das gewünschte Ergebnis:
1 | Key: B8AA9688DDD6528E86D8EEB45F866908 |
2 | IV: C5250301101055084D4D4D4D4D4D4D4D |
3 | Encrypted: 3F1EC0BB524BEEA88234B44D7D9F7888010E24593CAD21E27CE9E15AD82E215235AB08041AC46F6E19B8BF8A0BCA66840E3B7288699BDB9F7E81A85F3152E76161AEFEFCBF9F8F5A067161DBDF48D9EEE7091DEAA6C7D78CEC1E5831E3372A98 |
4 | Decrypted: 2F2F0B6E530400426EB80182016E8401C2016E320182026ED800C2026E5E0082036E8D01C2036E8D0182046E7401C2046E740182056E4501C2056E430182066E4301C2066E430182076E4301C2076E430182086EB800C2086E340002FD170000 |
Vielleicht hilft es ja als Inspiration.
Dieter S. schrieb: > Vielleicht hilft es ja als Inspiration. Tut es :) Deine bytesToHex() und hexToBytes() Funktionen machen den Unterschied zu den Java eigenen to-Bytes Umwandlungen. Woher wisst ihr und miller-alex.de/WMbus, dass der encryptete Teil bei `3F1EC0BB52...` anfängt? Und was mache ich mit dem Hex am Ende, ist das dann immer herstellerabhängig?
Torsten schrieb: > > Woher wisst ihr und miller-alex.de/WMbus, dass der encryptete Teil bei > `3F1EC0BB52...` anfängt? So steht es in der OMS Spezifikation. Wenn man sich auf der "Miller Alex" Web Seite den PDF Report erstellen läßt sieht man alle Details. > Und was mache ich mit dem Hex am Ende, ist das dann immer > herstellerabhängig? Meinst Du das letzte 0xFF? Die verschlüsselte Nachricht kann nur ein vielfaches der AES Blocklänge sein (16 Byte), daraus ergibt sich dass 0xFF nicht zur verschlüsselten Nachricht gehört.
Dieter S. schrieb: > So steht es in der OMS Spezifikation. Wenn man sich auf der "Miller > Alex" Web Seite den PDF Report erstellen läßt sieht man alle Details. > >> Und was mache ich mit dem Hex am Ende, ist das dann immer >> herstellerabhängig? > > Meinst Du das letzte 0xFF? Die verschlüsselte Nachricht kann nur ein > vielfaches der AES Blocklänge sein (16 Byte), daraus ergibt sich dass > 0xFF nicht zur verschlüsselten Nachricht gehört. Jetzt sehe ich klar. Mir wurden lauter verschiedene Hersteller Dokumente gegeben, die zeigen wo welche Daten sind. U.a. ist in diesen Dokumenten der Start des encrypteten Teils unterschiedlich. Was mir dazu noch so alles erzählt wurde, will ich erst gar nicht dran denken. Blocklänge ok, das verstehe ich :) Denke jetzt bin ich durch: Mein Problem waren die hexToByte und ByteToHex Geschichten und ein riesen Berg Datenmüll gepaart mit Dünnpfiff Laberei. Danke euch Allen :)
Oft wird da nicht in Hex (bzw. Sedezimal) kodiert, sondern in BCD (die Serienummer zB. bei MBus). Die Verschlüsselung ist auch nur "partial", d.h. da gibt es Records/Blöcke die verschlüsselt sind, enthalten meist die Messwerte (inkl. historischer Messwerte). Status Informationen wie das MBus Status Byte sind nicht verschlüsselt (Sensor Daten). Damit kann man zumindest sehen ob alles passt oder ob es Probleme gibt.
:
Bearbeitet durch User
Mladen G. schrieb: > Oft wird da nicht in Hex (bzw. Sedezimal) kodiert, sondern in BCD (die > Serienummer zB. bei MBus). ...du meinst den unverschlüsselten Teil!?!? > Die Verschlüsselung ist auch nur "partial", d.h. da gibt es > Records/Blöcke die verschlüsselt sind, enthalten meist die Messwerte > (inkl. historischer Messwerte). > Status Informationen wie das MBus Status Byte sind nicht verschlüsselt > (Sensor Daten). > Damit kann man zumindest sehen ob alles passt oder ob es Probleme gibt. Die unverschlüsselten Daten stehen immer am Anfang, oder?
Torsten schrieb: > > Die unverschlüsselten Daten stehen immer am Anfang, oder? Ich habe ja oben bereits auf die OMS Spezifikation verwiesen, da steht es drinnen. Und es gibt auch noch den "Annex N" dazu mit vielen Beispielen. Man muß wirklich nur mal reinschauen...
Danke, hab die OMS Spezifikation und der Report auf miller-alex ist top. Danke.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.