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);
mac.init(secretKey);
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)});
}