1

I've been going around in circles from Apple's CCCrypto docs, frameworks and other SO answers and am not making any headway.

I think I need to figure out how to get a IV from an encrypted string that I receive.

I receive a JSON payload which contains a String. That string is encrypted in AES-256-CBC. (From a Laravel PHP instance that I think uses OpenSSL). The string itself, decrypted, is another JSON object.

I have a pre-defined key.

The string I receive looks something like:

eJahdkawWKajashwlkwAkajsne8ehAhdhsiwkdkdhwNIEhHEheLlwhwlLLLLhshnNWhwhabwiIWHWHwh=

(but is a lot longer).

I'm trying to use this answer here: Issue using CCCrypt (CommonCrypt) in Swift

But am a) unsure if I'm properly converting the string to data and b) how to get the IV (initialization vector) from the string I receive.

Using that answer I do get "success" however when I try to pass it to the NSJSONSerailizer I never got a good result (it always fails) but I do get data out - I think it's garbage.

Edit:

I really mis-understood my original problem - I was receiving a base64 encoded string that I needed to decode into JSON (which went fine). Then using the linked answer and importing CommonCrypto I thought I'd be able to get usable data but I am not. @Rob Napier 's answer is extremely helpful. I think my problem is that the instance of laravel in question is using OpenSSL.

Community
  • 1
  • 1
Fred Faust
  • 6,696
  • 4
  • 32
  • 55

1 Answers1

2

There is no really commonly used standard format for AES encrypted data (there are several "standard formats" but they're not commonly used....) The only way to know how the data you have is encrypted is to look at the documentation for the data format, or failing that, the encrypting code itself.

In good encryption formats, the IV is sent along with the data. But in many common (insecure) formats, there is a hard-coded IV (sometimes 16 bytes of 0x00). If there's a password, you also need to find out how they've converted the password to a key (there are several ways to do this, some good, some horrible). In a good format, the key derivation may include some random "salt" that you need to extract from the data. You'll also need to know if there is an HMAC or similar authentication (which might be stored at the beginning or the end of the data, and may include its own salt).

There just isn't any good way to know without documentation from the sender. Any decently encrypted format is going to look like random noise, so figuring it out just by looking at the final message is pretty hard.

If this comes out of Laravel's encrypt function, then that seems to be ultimately this code:

public function encrypt($value)
{
    $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
    $value = base64_encode($this->padAndMcrypt($value, $iv));
    // Once we have the encrypted value we will go ahead base64_encode the input
    // vector and create the MAC for the encrypted value so we can verify its
    // authenticity. Then, we'll JSON encode the data in a "payload" array.
    $mac = $this->hash($iv = base64_encode($iv), $value);
    return base64_encode(json_encode(compact('iv', 'value', 'mac')));
}

If this is correct, then you should have been passed base64-encoded JSON with three fields: the IV (iv), the ciphertext (value), and what looks like an HMAC encrypted using the same key as the plaintext (mac). The data you've given above doesn't look like JSON at all (even after base-64 decoding).

This assumes that the caller used this encrypt function, though. There are many, many ways to encrypt, though, so you need to know how the actual server you're talking to did it.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thank you for the thoughtful reply. I understand what you're saying but would you be able to show an example of how one would get the IV out of the 16 bytes of a string? – Fred Faust Jan 15 '16 at 20:56
  • 2
    Which 16 bytes are the IV? There is no standard for this. It could be in several places, and might not be in the string at all. The question is "where did the encryptor put the IV, or is it hard-coded?" Only you have the documentation and code to answer that. – Rob Napier Jan 15 '16 at 21:26
  • I severely mis-understood my problem and ran across your framework. I'm trying to get everyone to switch to it. The Laravel being used calls openSSL at some point and from reading yours and other posts I see that is probably not going to work on iOS these days. – Fred Faust Jan 16 '16 at 01:35