AES 128 CBC FIPS 197 entschlüsseln

OP #7413897
Lesenswert?

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?

OP #7413992
Lesenswert?

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.

OP #7415294
Lesenswert?

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: 5E44A8340153940081087A034050050CBE58A7DBF052E98AC2122D5C7A74C4F6A8D9EA3A5BC709FA67012FB8B4CF5DB7EA294014FFD4F0CCEC210D78587C10F92648ACFF6EFF8A7E1301DD10923E9DA14F823C1B51C0ED5ABDB9DD9AD19BFBFF

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?

#7415309
Lesenswert?

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.

#7415398
Lesenswert?

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?

#7415517
Lesenswert?

[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.

OP #7416592
Lesenswert?

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.

#7416604
Lesenswert?

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.

OP #7453165
Lesenswert?

Jetzt habe ich auch eigene Daten, die sich entschlüsseln lassen :)

Key: B8AA9688DDD6528E86D8EEB45F866908

RAW: 7644C5250301101055087203011010C52555084D0060053F1EC0BB524BEEA88234B44D7D9F7888010E24593CAD21E27CE9E15AD82E215235AB08041AC46F6E19B8BF8A0BCA66840E3B7288699BDB9F7E81A85F3152E76161AEFEFCBF9F8F5A067161DBDF48D9EEE7091DEAA6C7D78CEC1E5831E3372A98FF

Die Seite miller-alex.de/WMbus sagt der IV ist C5250301101055084D4D4D4D4D4D4D4D.

Hier ist bei mir ein Problem mit dem Java Cipher:

1
IV: C5250301101055084D4D4D4D4D4D4D4D
2
java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long
3
  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?

#7453180
Lesenswert?

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.

OP #7455347
Lesenswert?

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 ;)

#7455389
Lesenswert?

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.

Angehängte Dateien:
#7455758
Lesenswert?

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.

OP #7455888
Lesenswert?

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 :)

#7455903
Lesenswert?

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.

OP #7456124
Lesenswert?

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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren