Created
December 4, 2017 14:07
-
-
Save nickreffitt/0ceb1f1a6f663e9ef3c1ea5aaa43c3d5 to your computer and use it in GitHub Desktop.
A utility class to verify signatures on a publisher's backend when using Tapdaq's Server-Side Rewarded Callbacks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.base.Strings; | |
import org.apache.commons.codec.binary.Base64; | |
import org.apache.commons.codec.binary.Hex; | |
import javax.crypto.Mac; | |
import javax.crypto.spec.SecretKeySpec; | |
import java.io.IOException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
public class CryptoUtil { | |
private static final String CHAR_ENCODING = "UTF-8"; | |
private static final String HMAC_ALGORITHM = "HmacSHA256"; | |
public static String calculateBase64EncodedMd5(String contentToEncode) throws NoSuchAlgorithmException, IOException { | |
MessageDigest digest = MessageDigest.getInstance("MD5"); | |
// Get the MD5 hash: | |
digest.update(contentToEncode.getBytes(CHAR_ENCODING)); | |
// Base-64 encode the result: | |
return new String(Base64.encodeBase64(digest.digest())); | |
} | |
public static String calculateHmac(String key, String data) throws Exception { | |
if (Strings.isNullOrEmpty(data)) { | |
throw new IllegalArgumentException("Data should not be null or empty"); | |
} | |
Mac sha256_HMAC = Mac.getInstance(HMAC_ALGORITHM); | |
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(CHAR_ENCODING), HMAC_ALGORITHM); | |
sha256_HMAC.init(secret_key); | |
return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes(CHAR_ENCODING))); | |
} | |
/** | |
* Re-creates the signature and generates a SHA-256 hash, returning true if the hmac value passed in | |
* from the request matches, otherwise false. | |
* | |
* @param eventId retrieve value from the request params | |
* @param rewardValue retrieve value from the request params | |
* @param idfa retrieve value from the request params | |
* @param httpMethod either POST or GET | |
* @param date taken from the 'Date' Header value | |
* @param url the callback URL entered on the dashboard | |
* @param privateKey the private key used for encryption, entered in the dashboard | |
* @param receivedHmac the value included in the 'hmac' Header, after the colon 'tapdaq:[this_value]' | |
* @return | |
* @throws Exception | |
*/ | |
public static boolean verifySignature(String eventId, String rewardValue, String idfa, | |
String httpMethod, String date, String url, | |
String privateKey, String receivedHmac) throws Exception { | |
String concatenatedDashboardRequiredFields = eventId + rewardValue + idfa; | |
String base64EncodedMd5 = calculateBase64EncodedMd5(concatenatedDashboardRequiredFields); | |
String capitalisedHttpMethod = httpMethod.toUpperCase(); | |
String signature = base64EncodedMd5 + capitalisedHttpMethod + date + url; | |
String hmac = calculateHmac(privateKey, signature); | |
return hmac.equals(receivedHmac); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment