Forum: Mikrocontroller und Digitale Elektronik AES 128 CBC FIPS 197 entschlüsseln


von Torsten (bitkorn)


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?

von Axel S. (a-za-z0-9)


Lesenswert?

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.

von Torsten (bitkorn)


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.

von Torsten (bitkorn)


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

von Sebastian R. (sebastian_r569)


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.

von Dieter S. (ds1)


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?

: Bearbeitet durch User
von Foobar (asdfasd)


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.

von Torsten (bitkorn)


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.

von Dieter S. (ds1)


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.

von Sebastian R. (sebastian_r569)


Lesenswert?

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.

von Torsten (bitkorn)


Lesenswert?

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?

von Dieter S. (ds1)


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.

von Torsten (bitkorn)


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

von Dieter S. (ds1)


Angehängte Dateien:

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.

von Torsten (bitkorn)


Lesenswert?

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?

von Dieter S. (ds1)


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.

von Torsten (bitkorn)


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

von Mladen G. (mgira)


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.

: Bearbeitet durch User
von Torsten (bitkorn)


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?

von Dieter S. (ds1)


Lesenswert?

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

von Torsten (bitkorn)


Lesenswert?

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
Noch kein Account? Hier anmelden.