DateTime format or coding - date

i have 3 parameters with date/time and status of phases of electricity meter:
28.11.2019 4:18 - all phases have power
28.11.2019 4:18 - all phases don't have power
28.11.2019 4:23 - all phases don't have power
But these data coded to hex like this:
FA 22 7C 27 07 FF E1
49 22 7C 27 07 08 F3
4E 22 7C 27 00 08 1D
And i don't know how it was did? I mean maybe there is some method to keep and transfer date/time or what?
34 [48 83 27] 07 C6 EA - 3.12.2019 09:01, </b>
38 [48 83 27] 00 E7 74 - 3.12.2019 09:01, </b>
89 [49 83 27] 07 10 38 - 3.12.2019 09:12, </b>
8E [49 83 27] 00 10 D6 - 3.12.2019 09:12, </b>
0E [4B 83 27] 07 21 EA - 3.12.2019 09:24, </b>
13 [4B 83 27] 00 42 74 - 3.12.2019 09:24,</b>
19 [4B 83 27] 07 63 2A - 3.12.2019 09:24,</b>
1D [4B 83 27] 00 63 A4 - 3.12.2019 09:24,</b>
21 [4B 83 27] 07 84 5A - 3.12.2019 09:25,</b>
25 [4B 83 27] 00 84 D4 - 3.12.2019 09:25,</b>
square brackets - i guess it's date. 4th byte is state of phases. I mean low halfbyte(or semibyte?) of 4th byte. 0x7(0b0111) - all phases have power, 0x0(0b0000) - al phases doesn't have power.

TL;DR: The first 4 bytes of each line is a little-endian count of time units since some epoch that is either January 1 or January 6, 1980.
Each timestamp is 4 bytes. When we look at the third last and the second last line, they both have 4B 83 27 within the square brackets that you have put, yet the time changes fro 9:24 to 9:25. The times are obviously truncated, there needs not be more than a second or two between them, but they are not the same. The solution I found was to include the byte before the square bracket in the timestamp.
Timestamps are little endian. The byte before the square bracket varies the fastest as time moves. The next byte varies a little. The remaining two bytes stay constant within the 24 minutes range you are giving. The obvious explanation is that 34 48 83 27 really means 0x27834834, that is, the bytes are reversed.
It took some experimentation, but two common epochs would fit:
January 1, 1980. In this case the time unit used for counting the time since the epoch is around 1 900 440 700 nanoseconds.
January 6 the same year. In this case the unit must be a little smaller, around 1 899 789 030 nanoseconds.
Both January 1 and January 6, 1980 are commonly used epochs. See the link at the bottom for documentation.
I have searched somewhat for an explanation for the size of the unit. Could it be some nice fraction of a second or of a day, for example? I haven’t found any reasonable explanation. I am probably missing something.
I have ignored the issue of time zone and UTC offset. The epoch is likely defined in UTC, and if the times given in the question are in your local time zone, for example, this adds a slight inaccuracy to my analysis.
In code
To convert from hex number to date and time we may use a simple method like the following in Java.
private static LocalDateTime epoch = LocalDateTime.of(1980, Month.JANUARY, 6, 0, 0);
private static int nanosPerUnit = 1_899_789_030;
private static LocalDateTime convert(int n) {
return epoch.plusNanos((long) n * (long) nanosPerUnit);
}
Demonstration:
int[] numbers = {
0x27834834,
0x27834838,
0x27834989,
0x2783498e,
0x27834b0e,
0x27834b13,
0x27834b19,
0x27834b1d,
0x27834b21,
0x27834b25
};
for (int n : numbers) {
System.out.format("%x %s%n", n, convert(n));
}
Output:
27834834 2019-12-03T09:01:20.396289720
27834838 2019-12-03T09:01:27.995445840
27834989 2019-12-03T09:12:08.224348950
2783498e 2019-12-03T09:12:17.723294100
27834b0e 2019-12-03T09:24:27.242281620
27834b13 2019-12-03T09:24:36.741226770
27834b19 2019-12-03T09:24:48.139960950
27834b1d 2019-12-03T09:24:55.739117070
27834b21 2019-12-03T09:25:03.338273190
27834b25 2019-12-03T09:25:10.937429310
The dates and times agree with those from the question. I leave it to you to insert January 1 and 1_900_440_700 nanoseconds and see that this too gives results that agree with the question.
Links
Endianness on Wikipedia
Epoch (computing) on Wikipedia

Related

Convert stange 3 byte HEX date format from DBF

I need to work with a DBF file (dBASE III PLUSE, with memo) which contains weirdly formatted date values. The values are saved as HEX numbers counting up for each day.
Now comes the weird part, the counter jumps (compare e.g. integer value) every month one and every year two values. Basically, it counts a 00 month and a 00 day.
EDIT: Further it counts for every month 31 days, e.g. end of February.
EDIT 2: Another strange implementation I didn't see before is, that each byte/hex value count's only until 7F and then the next byte count's up e.g. 2001-02-15 -> 2001-02-16...
HEX Integer Date * not a valid date
====================================================
2E 22 30 3023408 1970-00-00 *
2E 22 31 3023409 1970-01-00 *
2E 22 32 3023410 1970-01-01
2E 22 33 3023411 1970-01-02
2E 22 34 3023412 1970-01-02
[...]
2E 22 50 3023440 1970-01-31
2E 22 51 3023441 1970-02-00 *
2E 22 52 3023442 1970-02-01
[...]
2E 22 6D 3023469 1970-02-28
2E 22 6E 3023470 1970-02-29 *
2E 22 6F 3023471 1970-02-30 *
2E 22 70 3023472 1970-02-31 *
2E 22 71 3023473 1970-03-00 *
2E 22 72 3023474 1970-03-01
[...]
2E 25 30 3024176 1970-12-31
2E 25 31 3024177 1971-00-00 *
2E 25 32 3024178 1971-01-00 *
2E 25 33 3024179 1971-01-01
[...]
2E 7F 7F 3047295 2001-02-15
2F 00 00 3080192 2001-02-16
[...]
With this knowledge, I could generate a list from 1900-01-01 until 2038-01-18, see example.txt.
Is this a known pattern, I just never heard about it?
Is there a simple way to convert date back and forward?
As #js2010 pointed out it's probably the 3 byte Date of last update, in YYMMDD format structure, see dbase.com/Knowledgebase/INT/db7_file_fmt.htm . Though there isn't really a further explanation.

A Script To Convert Numbers

I was hoping someone could assist me in making a linux script that can take a number and convert it to this format.
Here is a few of examples:
number = 753082360700386 Converted = 7A 35 80 32 06 07 30 68
number = 653082360700387 Converted = 6A 35 80 32 06 07 30 78
number = 453082360700389 Converted = 4A 35 80 32 06 07 30 98
The number will always have one A and last pair of numbers
swapped from 89 to 98 and next set swapped from 03 to 30
going from right to left and adding spaces between each pair

Unrecognized status byte in Midi file

I've been working on Midi file for some time and I stuck on some kind of status byte of thing. According to the standard Midi file format there is no such a things. So, Can someone tell what is this 3 bytes information "00 a040". I know that "00" is the byte stands for delta time and 0xa0 should be status byte, If only I understood it correctly. Last 3 bytes located at line 18 is the only part I don't understand so far. After those 3 bytes, then comes the text meta event bytes lead by "00 ff01".
Midi File Line 18th to 19th:
ff 51 03 09 cc 90 00 c0 00 00 b0 07 64 00 0a 40
00 ff 01 20 62 64 63 61 34 32 36 64 31 30 34 61
The SMF specification says:
Running status is used: status bytes of MIDI channel messages may be omitted if the preceding event is a MIDI channel message with the same status.
So these bytes can be decoded as follows:
ff 51 03 09 cc 90: meta event: set tempo, 9CC90h = 642192 µs per quarter note
00: delta time
c0 00: set program 0 (piano) on channel 0
00: delta time
b0 07 64: set controller 7 (volumn) to value 100
00: delta time
  0a 40: running status (repeat B0h); set controller 10 (expression) to value 64
00: delta time
ff 01 20 ...: meta event: text: "bdca426d104a..."

WM-Bus extended layer decoding

I am trying to decrypt wm-bus telegram from Kamstrup Multical21 in C1 mode with Extended Link Layer.
The payload together with ELL info is following:
23 44 2D 2C 45 45 71 63 1B 16 8D 20 6A 31 FB 7C 20 39 A3 79 60 4B 90 BD FC BE 8D D8 CB 18 CE 77 DC 41 CE 8C
Analysing CI = 8D I found that there is a ELL with following data:
CI (1 byte) CC(1 byte) ACC(1 byte) SN(4 bytes) CRC(2 bytes)
8D 20 6A 31 FB 7C 20 39 A3
The documentation says that the buffer which should be decrypted shall contain CRC from ELL, i.e:
39 A3 79 60 4B 90 BD FC BE 8D D8 CB 18 CE 77 DC 41 CE 8C
I have got the AES key from the Manufacturer:
B9 7A 6D 4E C2 74 A4 6D 87 0E 31 27 D9 A0 AF 63
Initialization vector for ELL shall be:
M-field A-field CC-field SN-field FN BC
2D 2C 45 45 71 63 1B 16 20 31 FB 7C 20 00 00 00
After decrypting, I get the following result:
08 3a 5f ce b2 8d 51 97 94 a2 5b fb 61 ab 2e c0
e4 20 c8 2a 43 ff 3a 75 6f 93 d0 ac 8c 79 b7 a1
Since there is no 2F 2F in the beginning, something is wrong!
Can somebody help me and tell what I have done wrong?
Thanks in advance.
I had a look in the latest Kamstrup docs ("Wireless M-Bus Communication Kamstrup Water Meters - MULTICAL® 21 and flowIQ® water meters Mode C1 according to EN 13757-4:2013")
When I decrypt your packet I find:
25877968217E8E01000000000000000000
Firstly, it seems the Kamstrup decrypted packets does not start with 2F 2F.
The first 2 bytes of the decrypted packet is supposedly the PLCRC (I can't confirm that right now - don't have immediate access to the standard that defines the crc polynomial algorithm), and then the next byte is 79, which means it is a Compact Frame, then the next 4 bytes are 2 more CRCs, and then the next 2 bytes 0100 is probably the Info, which is manufacturer specific and I don't know how to interpret that yet.
This meter is probably R type 1, right? (on the face place, the "Con.:" parameter's 3rd last digit should be a 1) So its format would be [Info][Volume][Target Volume] - 2 bytes, 4 bytes, 4 bytes - I kind of assume that, since this packet is a compact packet, so I don't get the actual format the long packet would have, e.g. number of decimals - which normally you'd need - but your values are zeroes? so decimals doesn't matter. (the 'long' packet of course is every 6th packet or so?)
The IV I get is:
2D2C454571631B162031FB7C20000000
which is exactly the same as yours.
The encrypted packet I use is:
39A379604B90BDFCBE8DD8CB18CE77DC41
so I exclude the CE and 8C you had on yours?
When I put them in, the decrypted packet becomes:
25877968217E8E01000000000000000000BB49
which is pretty much the same packet with some more crc stuff at the back, I suspect, so I really do not get what you do to decrypt, since your result is completely different?
Ok, maybe you use AES/CBC/NoPadding, as in OpenMUC.
Kamstrup uses AES/CTR/NoPadding. That is how they don't have to decrypt multiples of 16 byte blocks? The way that looks in my Java code is as follows:
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
the hints here are very helpfull. There's one obstacle I stumbled across with the given message. The Length-Field is wrong and there are 2 bytes of garbage at the end.
I guess the original message was encoded in frame format B. That means the length field includes the frame CRCs and should be corrected after the CRCs are removed. After correcting the length to 0x21 (33 bytes + L-Field), I get the correct message and also can verify that the first 2 bytes of the decoded message contain the CRC16 of the remaining message.

APDU: "Conditions of use not satisfied" (69 85) while calculate signature

With a smart card Gemalto (IAS ECC), I would to calculate a signature by using private key stored on smart card. For this, I use APDU commands:
// Verify PIN
00 20 00 01 04 31 32 33 34
-> 90 00
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
-> 90 00
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
// Calculating the signature
00 2A 9E 9A 80
-> 69 85
My problem is the following: the las two commands return the error code "69 85", meaning "Conditions of use not satisfied".
I have already tried several solutions, but I obtain always the same error. How to resolve it? What does this code can mean?
After some tests, I discovered something interesting. When I replace cla "00" by "10", smart card returns a different response:
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
// Verify PIN
00 20 00 01 04 31 32 33 34
// Calculating the signature (I replace "00" by "10")
10 2A 9E 9A 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 12 13 14 15
I don't know if it's the good solution because smart card returns "90 00". But, it would return the content of my signature!
Thank you for your help!
Best regards
You are getting SW 6985 for
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
Since you have not set the correct context in current security environment.
Let me explain this below
First you performed VERIFY PIN command which was successful
// Verify PIN
00 20 00 01 04 31 32 33 34
-> 90 00
Then you performed MSE SET command,Where you set the security context.For this you have to understood how SE works(Please refer to section 3.5 fron IAS ECC v1.01).
At the time of personalisation, the Personaliser agent create SDO(Secure Data Object) inside the card.The reference to this SDO are mentioned in SE(Security Environment) in form of CRT(Control reference template).
// Create a context for security operation
00 22 41 B6 06 84 01 84 80 01 12
-> 90 00
Generally speaking, MSE SET command will always return SW 900 even if the SDO reference is wrong. Since it only return SW 6A80 when the template is wrong not when the reference is wrong.(The SDO reference is passed in tag 84)
After that you performed PSO HASH command
// Set the hash of the document
00 2A 90 A0 14 HASH OF DOCUMENT
-> 69 85
where the card return SW 6985(Condition of use not satisfied), This indicate the algorithm and SDO reference used for calculating Hash may wrong. Which is probably happening since the SDO reference which was sent during the time of MSE SET command is not available
Detecting error coming from MSE SET could be tricky since it return SW 9000.
For these type of situation you have to check the personalisation file carefully and need to match the MSE SET command with regard to SDO reference and supported ALGOs.
It may be useful to put the default context (e.g., cryptographic algorithms or
security operations) into the current SE in order to have few exchanges of MSE set commands.