0

I'm reverse engineering an API and I found out that it uses AES-256-CBC for encryption.
I also found out that it uses EVP_BytesToKey to encrypt HTTP requests. After I found out about this I tested it but I had some issues (probably because I'm inexperienced). I don't know where to put the password

And this is what needs to be decrypted: FP2xttTh/wm5Kr45Vh/PEvsdxgfL3NgxxMMk9hTkPfJd7vSJXTlhjiZlQajnBcMAVknANpv5FNCMRD+epDSOA2epKOzstSmhC0il2TlwgKqaT+97zomCMUCIfdaJYnLz5gBth1MIpxO30bx9zPg8cbOJcLnMmCo3vtSDCalgjHICf5FevI7DgrWnWC1U4wab0rx/rWhGFJ0sOW1ImDi9DkCy+guQZIrojbZxRlvGzv1mU/avP5hbKgWIheJpYQvvM12RyCNuVxjHK/oZ1mCQLVjvpED291lxsGTNHPUrc2NI7LCj/xOztjgsukpBP9K1nsUIgEyfVFUfTf5sh4QPccZnJ1bzKqPD

The person who told me the key and the way it's decrypted also gave me this

REMOVED

  • your question is somewhat incomplete, please assume we know only what you say not all what you think. what do you have exactly problem with (password is `args[ARG_INDEX_PASSWORD].getBytes(ASCII)` however in your case you may try base64 decoded value) – gusto2 Nov 03 '17 at 11:40
  • I added password and string to decrypt in the main method like [this](https://pastebin.com/BKxrBwxT) .But after i run it i get this `Exception in thread "main" java.lang.IllegalStateException: Bad algorithm, mode or corrupted (resized) ciphertext. at testEncryption.OpenSSLDecryptor.main(OpenSSLDecryptor.java:162)` I'm probably missing something stupid – Матеја Стевановић Nov 03 '17 at 11:53
  • @gusto2 Forgot to tag you,sorry – Матеја Стевановић Nov 03 '17 at 12:47
  • 1
    Your 'password' doesn't look like a password at all; after de-base64 it is the correct _size_ to be an AES-192 key (not 256) but its contents are obviously a truncated RSA public key which is (or would be) a very poor, low-entropy choice for a symmetric key. Your data cannot be AES-CBC ciphertext because after de-base64 it is not a multiple of 16 bytes, and it definitely isn't the normal 'Salted__' format of OpenSSL 'enc' encryption as linked (although EVP_BytesToKey does have other uses). Whatever you're trying to do is very badly screwed up. – dave_thompson_085 Nov 03 '17 at 13:59
  • @dave_thompson_085 The person who told me the key and the way it's decrypted also gave me this `#!/usr/bin/env bash # base64 data must be stored in a file named "...-tmp.decrypt" # Usage: decrypt.sh secret sessionId SALT="$(cat $2 | base64 -d | head -c +8 | od -A n -t x1 | head -n 1 | tr -d " ")" echo -n "Salted__" > $2.enc cat $2 | base64 -d >> $2.enc cat $2.enc | openssl aes-256-cbc -d -k "$1" -md md5 -S "$SALT" rm $2.enc ` And that the password is definitely the one in my post.I wanted to code in in Java – Матеја Стевановић Nov 03 '17 at 14:09
  • you could post this code from the start. `SALT` is hexadecimal encoding of the first 8 bytes without spaces (that will be IV). then you need to prepend "Salted__" to the decoded input (now the block padding shoukd be ok).. salt is part of the input?? – gusto2 Nov 03 '17 at 17:25
  • @gusto2 could you perhaps edit code to do that?I'm finding trouble understanding what you said (i'm not an native english speaker).Or if you can't edit it,can you explain what i need to change? Thanks for you help :D – Матеја Стевановић Nov 03 '17 at 18:16

1 Answers1

4

The person who told me the key and the way it's decrypted also gave me this

# base64 data must be stored in a file named "...-tmp.decrypt" 
# Usage: decrypt.sh secret sessionId 
SALT="$(cat $2 | base64 -d | head -c +8 | od -A n -t x1 | head -n 1 | tr -d " ")" 
echo -n "Salted__" > $2.enc cat $2 | base64 -d >> $2.enc cat $2.enc | openssl aes-256-cbc -d -k "$1" -md md5 -S "$SALT"

what we have here

  • the salt is made of first 8 bytes of the input
  • the aes-256-cbc is used

Constants:

 private static final int SALT_LENGTH = 8; 
 private static final int ITERATIONS = 1;
 private static final int KEY_SIZE_BITS = 256;

 private static final int INDEX_KEY = 0;
 private static final int INDEX_IV = 1;

divide salt and input

        // iv is 8 bytes of the input
        byte[] inputBytes = Base64.getDecoder().decode(INPUT);
        byte[] salt = new byte[SALT_LENGTH];
        System.arraycopy(inputBytes, 0, salt, 0, SALT_LENGTH);
        byte[] encrypted = new byte[inputBytes.length - SALT_LENGTH];
        System.arraycopy(inputBytes, SALT_LENGTH, encrypted, 0, encrypted.length);

and decrypt (where did you get the original code from? attribution to the original author wouldn't hurt)

        Cipher aesCBC = Cipher.getInstance("AES/CBC/Pkcs5Padding");
        MessageDigest md5 = MessageDigest.getInstance("MD5");

        // --- create key and IV  ---
        // the IV is useless, OpenSSL might as well have use zero's
        final byte[][] keyAndIV = EVP_BytesToKey(
                KEY_SIZE_BITS / 8,
                aesCBC.getBlockSize(),
                md5,
                salt,
                PASSWORD_STRING.getBytes("UTF-8"),
                ITERATIONS);
        SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
        IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);

        // --- initialize cipher instance and decrypt ---
        aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decrypted = aesCBC.doFinal(encrypted);

        System.out.println(new String(decrypted, "UTF-8"));

and we get a result

  {"difficulty":5,"friend_id":1962395051,"is_playing_script":true,
 "selected_team_num":3,"support_items":
 [{"quantity":2,"support_item_id":6},{"quantity":2,"support_item_id":1505},{"quantity":2,"support_item_id":1202},{"quantity":2,"support_item_id":1701}]}

Still I see 2 things missing:

  1. password strength

as @dave_thompson_085 pointed out, the password looks like part of a PEM file and I agree with him. That's very wrong as the PEM file has defined rigid schema and that will effectively lower randomness of the password

I advice to use really random password, e,g, generated as

openssl rand -hex 16
openssl rand -base64 16
  1. authenticated encryption

the ciphertext doesn't contain any integrity information so in case the ciphertext is be altered, there is no option the alteration is detected, so you cannot ensure integrity

extra integrity information needs to be sent along the ciphertext (e.g. hmac of the ciphertext)

gusto2
  • 11,210
  • 2
  • 17
  • 36