This might be a bit difficult to follow without context, but the gist of it is the following; I'm trying to reverse a certain application, and part of what I"m attempting to reverse in the app generates 3 unique colors based on a string passed via API requests. I know that I've successfully reversed the API properly as the other data I receive works perfectly and I've built out a clone of the client that properly interacts with the API. What I'm stuck on is three color codes that are generated every day, based on a specific key passed by the API.

Today, 7/26/17, the color codes are [#c698c8, #72555f, #2f1021], created from the string that the API passed - 87gs4.

I've disassembled the Java code and traced the generation of these colors to the following set of functions. I've verified that it is indeed the string I grabbed from the API responsible for generating these. The SALT mentioned in the functions is generated from a datetime formatted as yyyyMd - in the case of today's colors, the salt is 20170727, or as the HMAC signature function generates it, 20170727 is the input with 87gs4 as the key.

The resulting signature is then taken (64 hex characters), and only the first 18 are saved, then split up into 3 to form the color codes. Therefore, I know the signature I'm looking for (for today) begins with c698c872555f2f1021 - but for some reason, my results do not achieve this. I've checked to make sure I"m using the right key/input order (even reversed it just in case), and I'm getitng 9a0ca25fff8eeccdbaf741436ddacf364f517adcb28299f0544c72a67dca2089 or 30c21ae7995415220e427588e451cbdd58d84785bcd58f8e3f0db2ca0fc104c4. I've also checked lettercase to no avail.

I don't have tomorrow's colors, but I have the data from the API and know the salt - tomorrow it will be 20170728 and kRG86.

I have verified that there's no external manipulation via getColorBand() or getSalt() before the values are passed to create the signature, and I've even had another pair of eyes take a look at this - someone who is fairly experienced with this kind of stuff - he thinks that maybe we're missing something in the byte to hex (and vice versa) conversation that is causing incorrect results, but that we're on the right track and that an HMAC-SHA256 hash generator using the yyyyMd salt and the data I received is correct in that it should be generating the right data.

Code for the actual string manipulation and generation:

        String color = this.hexFortmat.substring(0, 6);
        ImageView colorBand1 = ((ImageView) DecompiledFile.this.findViewById(R.id.image_view1));
        ImageView colorBand2 = ((ImageView) DecompiledFile.this.findViewById(R.id.image_view2));
        ImageView colorBand3 = ((ImageView) DecompiledFile.this.findViewById(R.id.image_view3));
        String hexFortmat = DecompiledFile.bin2hex(this.mdbytes);
        byte[] mdbytes = DecompiledFile.generateHmacSHA256Signature(DecompiledFile.this.getSalt(), DecompiledFile.this.getColorBand());
        boolean performAllTimerFunctions = true;
        TextView specialInstruction = ((TextView) DecompiledFile.this.findViewById(R.id.textView9));
        boolean visibleColorBand = false;
        boolean visibleSpecialInstruction = false;

Relevant signature code:

public static byte[] generateHmacSHA256Signature(String data, String key) throws GeneralSecurityException, IOException {
    try {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StringEncodings.UTF8), HMAC_SHA_256);
        Mac mac = Mac.getInstance(HMAC_SHA_256);
        return mac.doFinal(data.getBytes(StringEncodings.UTF8));
    } catch (UnsupportedEncodingException e) {
        throw new GeneralSecurityException(e);

static String bin2hex(byte[] data) {
    return String.format("%0" + (data.length * 2) + "X", new Object[]{new BigInteger(1, data)});

1 Answer 1


you possibly have an extra 0 in the month





it is padded according to format string


!enter image description here

  • How would this work on later months? It will change to 2 digits if formatted as yyyyMd?
    – Thirk
    Commented Jul 28, 2017 at 3:06
  • maybe hex month possibly the hash matches the input and output so it is close you may have to look somewhere near
    – blabb
    Commented Jul 28, 2017 at 3:14
  • 2
    For those curious: the number of Ms and ds specifies the minimum number of digits, any number of digits less than the amount of Ms or ds will be left zero-padded. So in this particular case, Oct, Nov, Dec will be two digits. And days with a single digit will be single digit. Source: docs.oracle.com/javase/7/docs/api/java/text/…
    – Ilya O.
    Commented Jul 28, 2017 at 3:17
  • ilya beat me and commented that explains the format i also added a screenshot to the answer which shows how padding seems to work
    – blabb
    Commented Jul 28, 2017 at 3:38

Your Answer

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

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