0

I need to decrypt a string, returned from an API that was originally encrypted using c# functions based on those here >

http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp

I need to decrypt using PHP.

A password and a key have been provided I've made several attempts to decrypt using openssl_decrypt, but I'm unsure how to use the key in the decryption?

[update] I have been told that the password I have been given is the basis for the iv, and that the padding is PKCS7, the problem is that I have no idea how to create the iv.

I have the following example input/keys, but I'm not sure how to use the password as I've been told it is the iv do I need to pad it to the correct length, if so how?

Original string: 'Mondays Suck'
Password/salt: 'this_is_the_password'
Input key: 'this_is_the_input_key'
Encrypted String: 'mAqsxJaA0jpQdefBPug2tw=='
joobe
  • 1
  • 2
  • There is much that is missing in your code example: example inputs, example outputs and expected outputs. You should try to read the code. A quick glace reveals that the key is derived through PBKDF2 and PKCS#7 padding is used instead of mcrypt's zero padding. The C# code is not that stellar, because it lacks authentication and randomization. Why don't you just use [RNCryptor](https://github.com/RNCryptor)? – Artjom B. Aug 05 '16 at 17:03
  • Thanks for commenting, I have no control over the API code. – joobe Aug 08 '16 at 08:09
  • No, a password is not an IV. They are completely different. Also, Stack Overflow is not a code translation service. Try it yourself and maybe somebody will help you at the last step. – Artjom B. Aug 08 '16 at 19:03
  • I have tried it, using openssl_decrypt and mcrypt_decrypt, but I don't know how to create the correct iv – joobe Aug 09 '16 at 11:48
  • Ah, I see. The code that you've used as a basis is really bad. Usually, the IV is simply prepended to the ciphertext and sliced off before decryption, but the code you've tried to port simply hides the IV from you. You cannot use the code as it is shown there and successfully decrypt something. If you can't control over the API code, then you have a broken API. I don't see how it is supposed to work. – Artjom B. Aug 09 '16 at 20:02
  • Thank you, I think my problem is becoming clearer, I need to discover how to recreate the iv so that it can be removed from the encrypted string? – joobe Aug 10 '16 at 09:02
  • is it possible to get the iv, http://security.stackexchange.com/questions/29106/openssl-recover-key-and-iv-by-passphrase – joobe Aug 24 '16 at 09:19
  • Sorry, I missed that the IV is statically generated from the password which is just as bad as simply hardcoding an IV. Note that Stack Overflow is not a code translation service. Try it yourself and if you're stuck, come back with an [MCVE](/help/mcve) – Artjom B. Aug 24 '16 at 19:23

1 Answers1

0

If there indeed is any ciphertext packing going on, it would be to include the initialization vector (IV), assuming one was even used in the first place.

In short, if I encrypted a string with AES-128:

  1. I'd likely be using PBKDF2 to take a weak passphrase and a salt to generate secret key material used to do the encryption itself.
  2. I'd generate a message-specific (i.e. one-time use) initialization vector for ciphering
  3. I'd then use the secret key [material] and IV generated in the previous steps to encrypt the string using AES-128: E(plaintext, key, iv)
  4. If the string is longer than 16 bytes, I'd have to also use an encryption mode such as CBC, CTR, etc.
  5. For convenience, I would "pack" the IV (not required to be kept secret) in front of the ciphertext by simply concatenating: iv+ciphertext
  6. If I was serious about doing it right, I would generate a message authentication code of the ciphertext and append that as well such that I would now have: iv+ciphertext+mac

On decrypt, I would then verify the MAC before decrypting (if I was to do it right), and I would then need to separate the IV from the ciphertext, and then run it through my decryption routine: D(ciphertext, key, iv).

Another thing to keep in mind is encoding as sometimes we pass around Base64-encoded strings as a more print-friendly format than raw data. You of course would have to decode that before working on unpacking, decrypting, etc.

For academic purposes, I created Crypto Implementation (DRAFT) back when I was teaching myself crypto and wanted to document processes and best practices as well as keep all "moving parts" in view as a reference when I had to work on this stuff. Lots of rules to follow, but all in all, a lot of good learning and professional development opportunities.

Hope that helps some!

Edit: Per my comment below, I just looked at the original source code for the C# implementation. It appears the only way to decrypt this in PHP would be to have a PHP equivalent of C#'s Rfc2898DeriveBytes as this is the part responsible for generating your IV. Study the DecryptRijndael routine and you'll see where it gets the IV from (it basically implies using the same salt). If you truly have no control or influence over the encryption routine, you might be inclined to hack up a solution involving using C# DLLs in PHP and then call the DecryptRijndael method from PHP.

Matt Borja
  • 1,509
  • 1
  • 17
  • 38
  • It helps, but it's not the answer as I said I have no control over the encryption, thanks – joobe Aug 24 '16 at 09:24
  • You basically need the IV and I was more or less describing *how* the IV gets passed around; sometimes it prepends the ciphertext, stored in a separate column, etc. and where you might go to look for it and then how you would use it in a decryption routine. I did a quick check on your ciphertext and it comes out to 16 bytes when decoded, suggesting this is just the ciphertext and doesn't include the IV. Can you elaborate more on what the "Input key" is you referenced in your post? – Matt Borja Aug 24 '16 at 15:47
  • I just looked at the original source code for the C# implementation. It appears the only way to decrypt this in PHP would be to have a PHP equivalent of C#'s `Rfc2898DeriveBytes` as this is the part responsible for generating your IV. Study the `DecryptRijndael` routine and you'll see where it gets the IV from (it basically implies using the same salt). If you truly have no control or influence over the encryption routine, you might be inclined to hack up a solution involving [using C# DLLs in PHP](https://stackoverflow.com/questions/7874544/how-to-create-c-sharp-dll-to-use-in-php). – Matt Borja Aug 24 '16 at 15:54