|
|
|
@ -1,5 +1,8 @@
|
|
|
|
|
package au.com.royalpay.payment.manage.shopify.support;
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.codec.DecoderException;
|
|
|
|
|
import org.apache.commons.codec.binary.Base64;
|
|
|
|
|
import org.apache.commons.codec.binary.Hex;
|
|
|
|
|
import org.apache.commons.codec.digest.HmacAlgorithms;
|
|
|
|
|
import org.apache.commons.codec.digest.HmacUtils;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
@ -14,6 +17,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|
|
|
|
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.security.Security;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Locale;
|
|
|
|
|
|
|
|
|
|
public class HmacVerificationUtil {
|
|
|
|
@ -25,10 +29,10 @@ public class HmacVerificationUtil {
|
|
|
|
|
public static boolean checkParameters(String message, String secret, String hmac) {
|
|
|
|
|
try {
|
|
|
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
|
|
|
SecretKey secretKey = new SecretKeySpec(secret.getBytes("UTF8"), "HmacSHA256");
|
|
|
|
|
SecretKey secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
|
|
|
|
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
|
|
|
|
|
mac.init(secretKey);
|
|
|
|
|
byte[] digest = mac.doFinal(message.getBytes("UTF-8"));
|
|
|
|
|
byte[] digest = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
String marshal = new HexBinaryAdapter().marshal(digest).toLowerCase(Locale.ROOT);
|
|
|
|
|
return StringUtils.equals(marshal, hmac);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -37,28 +41,34 @@ public class HmacVerificationUtil {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean hmacSHA256(String input, String key, String hmac) {
|
|
|
|
|
String encode = encode(input, key, HmacAlgorithms.HMAC_SHA_256);
|
|
|
|
|
logger.debug("input={}; key={}; encoded={}; request-hmac: {}", input, key, encode, hmac);
|
|
|
|
|
return StringUtils.equals(encode, hmac);
|
|
|
|
|
if (isHex(hmac)) {
|
|
|
|
|
try {
|
|
|
|
|
byte[] requestHmac = Hex.decodeHex(hmac);
|
|
|
|
|
byte[] hmacRes = hmac(input, key, HmacAlgorithms.HMAC_SHA_256);
|
|
|
|
|
String hmacHex = Hex.encodeHexString(hmacRes);
|
|
|
|
|
logger.debug("hex-mode: input={}; key={}; encoded={}; request-hmac: {}", input, key, hmacHex, hmac);
|
|
|
|
|
return Arrays.equals(requestHmac, hmacRes);
|
|
|
|
|
} catch (DecoderException ignore) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//base64
|
|
|
|
|
byte[] hmacRes = hmac(input, key, HmacAlgorithms.HMAC_SHA_256);
|
|
|
|
|
String hmacB64 = Base64.encodeBase64String(hmacRes);
|
|
|
|
|
logger.debug("b64-mode: input={}; key={}; encoded={}; request-hmac: {}", input, key, hmacB64, hmac);
|
|
|
|
|
byte[] requestHmac = Base64.decodeBase64(hmac);
|
|
|
|
|
return Arrays.equals(requestHmac, hmacRes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String encode(String input, String key, HmacAlgorithms algorithm) {
|
|
|
|
|
Mac mac = HmacUtils.getInitializedMac(algorithm, key.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
byte[] content = input.getBytes(StandardCharsets.UTF_8);
|
|
|
|
|
byte[] signResult = mac.doFinal(content);
|
|
|
|
|
return bytesToHex(signResult);
|
|
|
|
|
private static boolean isHex(String str) {
|
|
|
|
|
return str != null && str.toUpperCase(Locale.ROOT).matches("^[0-9A-F]$");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String bytesToHex(byte[] hash) {
|
|
|
|
|
StringBuilder hexString = new StringBuilder();
|
|
|
|
|
for (byte b : hash) {
|
|
|
|
|
String hex = Integer.toHexString(0xff & b);
|
|
|
|
|
if (hex.length() == 1) {
|
|
|
|
|
hexString.append('0');
|
|
|
|
|
}
|
|
|
|
|
hexString.append(hex);
|
|
|
|
|
}
|
|
|
|
|
return hexString.toString();
|
|
|
|
|
private static byte[] hmac(String input, String key, HmacAlgorithms algorithm) {
|
|
|
|
|
Mac mac = HmacUtils.getInitializedMac(algorithm, key.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
byte[] content = input.getBytes(StandardCharsets.UTF_8);
|
|
|
|
|
return mac.doFinal(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|