Background: I am currently looking to make some diagnostic software interoperable with other software, but all communication that occurs in this software is encrypted with AES-128-CBC. A sample request is included below. The binary is also linked to at the bottom for those who wish to examine it.

  "api-version": "1.0",
  "mac-model": 69,
  "action": 1,
  "timestamp": 1517862344000,
  "service-location": false,
  "ksess": "X+syUFRBrn9ytyg0qDaG/+W7wN6MiuHyJzNuLj/y/vbjpeDJoZjAP65xTWiSLrgJJMCgAyoKc8Ss3oUjq1gRYeTz8oEjjUmU2ym+f6pwoVsrVJ+EtQ/WDnhENjdAjE2vNOuiD1v/ncSk/gk1AUiZwK8tpPPEytSv0R9XlVtVpg8KlK1SF66Vl2hRjovko9uqIxs98iymZ42iWkff39DQoclbngKTbLItUeXUbzwBI6thXkNiTYDmdm3SZUJrK6TS7ZoOxH/4eEJXDprf9pImEg7r0PmE4pPXSXSmuLVPAwHjWp0riVIVw0DGgQ4cfABmCh/oFxxl/Q5rzkvsKQuKeg==",
  "hmac": "89FA90002E4FA47C83FAEF1AC378B51D5A1CD2DB",
  "data": "MtN0XjxexXRb9GNh3pSJNW0jxvLZm45alwSbJ40fVXowOnKQpaD7Yc3exBCvmw1z//a+iQtOdpBV/NdHe78hj8oxQJ+4iBDsM6tv6PEB2OeNFJnKuQ5R0azq527npjMAuPWvZszotJkB7FBiF3YjbK6QPCBDURybanqUCJrO3Yao6+Qfa4P41VFbZab0FhoJ",
  "data2": "xgffrf24+Poxd6iS+r7nC5KDD6s="

I have worked out how the AES key is generated, and have been able decrypt the encrypted data, except for the first block, which obviously uses the IV during encryption. The IV is generated based on the timestamp, I have included a picture of the disassembled function below:

Screenshot of IV generation function disassembly

From what I can tell, the function is basically doing this (Objective C):

double timestamp = 1517862344;
double t1 = timestamp * 1000.0;
uint64_t t2 = (uint64_t)timestamp;
NSData *data = [NSData dataWithBytes:&t2 length:16];
NSLog(@"%@", data);

Where the data logged is the hex string for the given integer. This is further backed up with the fact that if I decrypt the base64 encoded data


with the key (hex) 7286276c0adb764ff1926bde8a12cbe6 and IV 4055a56761010000000054557a167642 (output from the aforementioned Obj C code, as (128 AES CBC w/ PKCS7 padding) the resulting decrypted data is:


where the correct output would be:


Hence, my question is, given that the only data that is transmitted is that which is present in the sample request, and the decryption of the first block is partially successful, what have I misinterpreted in terms of generating the IV that enables one to properly decrypt the last part of the first block? A secondary question, if someone knows the answer, is why is it that the first block is successfully partially decrypted even when the IV is not completely correct?

Link to the binary: https://www.dropbox.com/s/03mznlgsflkfn42/TA?dl=0

2 Answers 2


why is it that the first block is successfully partially decrypted even when the IV is not completely correct?"

You can understand this, if you have a look at the CBC decryption diagram. In this mode, the IV is xor to the decrypted first block. CBC mode decryption

So, if your IV is partially correct, then the decrypted plaintext will be partially correct also. Therefore the problem is that only the first half of your IV is correct. In case of the second half of the IV, you used the binary representation of the double value, while the first half is the timestamp after converting it to an integer value. Although I did not check, but I think you have to convert the timestamp to integer and perform a bitwise complement (~) operation to get the second half of the IV.

  • Thank you for the insightful explanation. A bitwise complement of the Integer representation of the timestamp was indeed the solution.
    – aHiltn
    May 8, 2018 at 10:17

In AES CBC if you're encrypting the data, it's YOU who specify this IV, and usually it's just random bytes. So basically you don't care about how this Objective C code does this randomization, just use your own random data. IV is then stored within the encrypted data, at the very beginning.

At the decryption side, AES CBC gets IV from the encrypted data and just uses it.

So, unless you're doing academically correct reversing, you don't need to spend time on understanding how random data is generated in this particular case.

  • In most cases I believe you are correct, the IV is just prephended to the cipertext, but I do not believe it's a requirement. In this case, it does not appear to be prepended. With regards to not needing it, as you can see, without it, the first block does not get decrypted correctly. My assumption was that the IV must be known in order for this to work?
    – aHiltn
    May 8, 2018 at 10:00
  • Are you sure that you extract IV and pass it to 'aes_cbc_encrypt' properly? May 8, 2018 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.