3

can anyone explain the following code? is it possible to retrieve the encryption key? I think the code was heavily obfuscated in addition to obfuscation, I can recognize it is using algorithms like DESEDE with CBC and PKCS5Padding to encrypt http post traffic from the app. my question is does any one know how to retrieve the key here?

package c.e.a.a.g;

import a.a;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.regex.Pattern;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class b {

    /* renamed from: a reason: collision with root package name */
    private static volatile b f4799a;

    /* renamed from: b reason: collision with root package name */
    private byte[] f4800b = null;

    /* renamed from: c reason: collision with root package name */
    private String f4801c;

    private b() {
        try {
            this.f4801c = a.a(new byte[]{97, 110, 100, 95, 50, 51, 116, 107, 108, 35, 95, 97, 105, 116, 33}, new byte[]{75, 24, 109, 27, -24, -51, 22, -58, -44, -74, 21, 91, -88, 48, -52, -63, 69, -67, 71, 17, 116, 77, 70, -94, 41, 121, 20, 120, 8, 121, 33, 77});
        } catch (GeneralSecurityException e2) {
            e2.printStackTrace();
        }
        this.f4800b = e(this.f4801c);
    }

    public static b a() {
        if (f4799a == null) {
            synchronized (b.class) {
                if (f4799a == null) {
                    f4799a = new b();
                }
            }
        }
        return f4799a;
    }

    private final String c(String str) {
        try {
            Cipher instance = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
            instance.init(2, new SecretKeySpec(this.f4800b, "DESede"));
            return a(instance.doFinal(new a().a(str)));
        } catch (Exception e2) {
            e2.printStackTrace();
            return null;
        }
    }

    private final String d(String str) {
        try {
            Cipher instance = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
            instance.init(1, new SecretKeySpec(this.f4800b, "DESede"));
            try {
                return Base64.encodeToString(instance.doFinal(str.getBytes()), 0);
            } catch (IllegalBlockSizeException e2) {
                e2.printStackTrace();
                return "";
            } catch (BadPaddingException e3) {
                e3.printStackTrace();
                return "";
            }
        } catch (NoSuchAlgorithmException e4) {
            e4.printStackTrace();
        } catch (NoSuchPaddingException e5) {
            e5.printStackTrace();
        } catch (InvalidKeyException e6) {
            e6.printStackTrace();
        }
    }

    private final byte[] e(String str) {
        try {
            return MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e2) {
            e2.printStackTrace();
            return null;
        } catch (UnsupportedEncodingException e3) {
            e3.printStackTrace();
            return null;
        }
    }

    public String b(String str) {
        StringBuilder sb = new StringBuilder();
        sb.append(str);
        sb.append(b());
        return d(sb.toString());
    }

    private String b() {
        int nextInt = new Random().nextInt(999999);
        StringBuilder sb = new StringBuilder();
        sb.append("|");
        sb.append(nextInt);
        return sb.toString();
    }

    public String a(String str) {
        return c(str).split(Pattern.quote("|"))[0];
    }

    public b(String str) {
        this.f4800b = e(str);
    }

    private final String a(byte[] bArr) {
        StringBuffer stringBuffer = new StringBuffer();
        for (byte b2 : bArr) {
            stringBuffer.append((char) b2);
        }
        return stringBuffer.toString();
    }
}

an example of encrypted http post request produced by this code is like following:

{"MobileUsersBE":{"AppVersion":"vB0gg8dKw8/ssTAXDUHLDw==\n","DeviceCode":"NUIDvs43seBumI3SU7Q1R/NWzO0ylo08jPjWcGUxZsFCjEu/IEjcEUYM4V6zswVc\n","DeviceType":"android","GCMCellId":"","Password":"P4fM264BxQXhd3RQu5vk8w==\n","UserName":"i2WZyhFJ9CZTx40Th83siw==\n"},"ServiceUsersBE":{"AppVersion":"ZA+PaD1HcAVZ384ENwEWBw==\n","DeviceCode":"NUIDvs43seBumI3SU7Q1R/NWzO0ylo08jPjWcGUxZsFOFoCbYVotoPrT8YV4yEHL\n","DeviceType":"android","Password":"t1h6/ATZ26VA8nS+fcnvkv0wtPbV8onO\n","TransactionCode":"vfTVe1PFdoFSMOdyYSxAI33cLtBw3z3uUrzOGlZJafQYzgg+Te+n/sDv/nyll3T2","UserName":"N67a2TEuY68jsRadkP0JGrh64aKxVin1\n"}}
2
  • With ref. to the code you posted, the key is derived as md5(this.f4801c). You need to find out what the function a.a is doing with the two byte arrays.
    – 0xec
    Mar 20, 2020 at 19:15
  • hello bro @0xec , I have posted the source code of a.a in here [ pastebin.com/L03kwbpj ] , appreciate your help, in some cases in this method code looked like it makes decryption. take a look and i appreciate your help.
    – hanan
    Mar 21, 2020 at 6:23

1 Answer 1

3

The encryption key is stored in the variable f4800b. It comes out to the following byte array.

43, 57, 97, -68, -63, -61, -40, 9, 50, 87, -104, 101, 63, 34, -78, 60

The cipher algorithm used is Triple-DES in ECB mode. It can be decrypted by the following snippet. Note that it requires the BouncyCastle Crypto provider for Java.

import java.security.*;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Main
{
    public static void main(String args[]) throws Exception
    {
        Security.addProvider(new BouncyCastleProvider());
        byte key[] = new byte[] {43, 57, 97, -68, -63, -61, -40, 9, 50, 87, -104, 101, 63, 34, -78, 60};

        //Base64 encoded cipher text here
        byte ct[] = Base64.getDecoder().decode("i2WZyhFJ9CZTx40Th83siw==");

        Cipher instance = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
        instance.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "DESede"));
        String pt = new String(instance.doFinal(ct));
        System.out.println(pt);
    }
}

Sample output

Using the JSON snippet you provided

{
   "MobileUsersBE":{
      "AppVersion":"vB0gg8dKw8/ssTAXDUHLDw==\n",
      "DeviceCode":"NUIDvs43seBumI3SU7Q1R/NWzO0ylo08jPjWcGUxZsFCjEu/IEjcEUYM4V6zswVc\n",
      "DeviceType":"android",
      "GCMCellId":"",
      "Password":"P4fM264BxQXhd3RQu5vk8w==\n",
      "UserName":"i2WZyhFJ9CZTx40Th83siw==\n"
   },
   "ServiceUsersBE":{
      "AppVersion":"ZA+PaD1HcAVZ384ENwEWBw==\n",
      "DeviceCode":"NUIDvs43seBumI3SU7Q1R/NWzO0ylo08jPjWcGUxZsFOFoCbYVotoPrT8YV4yEHL\n",
      "DeviceType":"android",
      "Password":"t1h6/ATZ26VA8nS+fcnvkv0wtPbV8onO\n",
      "TransactionCode":"vfTVe1PFdoFSMOdyYSxAI33cLtBw3z3uUrzOGlZJafQYzgg+Te+n/sDv/nyll3T2",
      "UserName":"N67a2TEuY68jsRadkP0JGrh64aKxVin1\n"
   }
}

Shown below are the ciphertexts and the corresponding plaintext to which it decrypts to.

vB0gg8dKw8/ssTAXDUHLDw==
2.3|138771
NUIDvs43seBumI3SU7Q1R/NWzO0ylo08jPjWcGUxZsFCjEu/IEjcEUYM4V6zswVc
8f850645-36ec-350a-8bb3-09c004daeb14|36159
P4fM264BxQXhd3RQu5vk8w==
test1234|364081
i2WZyhFJ9CZTx40Th83siw==
test|55664

Note that each plain text has a random number appended at the end after the | sign. This acts like a salt so that identical plain-texts do not encrypt to the same ciphertext.

1
  • 1
    Comments are not for extended discussion; this conversation has been moved to chat.
    – 0xC0000022L
    Mar 22, 2020 at 23:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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