package src.main; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.regex.*; import java.util.*; public class UrlAuth { private static String getHashString(String algorithm, String text) { MessageDigest hash = null; try { hash = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } hash.update(StandardCharsets.UTF_8.encode(text)); String format = "%x"; if (algorithm == "SHA-256") { format = "%064x"; } return String.format(format, new BigInteger(1, hash.digest())); } private static String getRandomString(int length) { int leftLimit = 48; // numeral '0' int rightLimit = 122; // letter 'z' Random random = new Random(); String str = random.ints(leftLimit, rightLimit + 1) .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) .limit(length) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString(); return str; } private static Map splitUrl(String url) { String pattern = "^(http://|https://)?([^/?]+)(/[^?]*)?(\\?.*)?$"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(url); Map result = new HashMap<>(); String scheme = "", domain = "", uri = "", args = ""; if (m.find()) { scheme = m.group(1) == null ? "http://" : m.group(1); domain = m.group(2) == null ? "" : m.group(2); uri = m.group(3) == null ? "/" : m.group(3); args = m.group(4) == null ? "" : m.group(4); } result.put("scheme", scheme); result.put("domain", domain); result.put("uri", uri); result.put("args", args); return result; } private static String genTypeAUrl(String url, String key, String signName, String uid, long ts, String hashAlgo) { Map uriInfo = splitUrl(url); String scheme = uriInfo.get("scheme"), domain = uriInfo.get("domain"), uri = uriInfo.get("uri"), args = uriInfo.get("args"); String rand = getRandomString(10); String text = String.format("%s-%d-%s-%s-%s", uri, ts, rand, uid, key); String hash = getHashString(hashAlgo, text); String authArg = String.format("%s=%d-%s-%s-%s", signName, ts, rand, uid, hash); if (Objects.equals(args, "")) return String.format("%s%s%s?%s", scheme, domain, uri, authArg); else return String.format("%s%s%s%s&%s", scheme, domain, uri, args, authArg); } private static String genTypeBUrl(String url, String key, long ts, String hashAlgo) { Map uriInfo = splitUrl(url); String scheme = uriInfo.get("scheme"), domain = uriInfo.get("domain"), uri = uriInfo.get("uri"), args = uriInfo.get("args"); String tsStr = new SimpleDateFormat("yyyyMMddHHmm").format(ts * 1000); String text = String.format("%s%s%s", key, tsStr, uri); String hash = getHashString(hashAlgo, text); return String.format("%s%s/%s/%s%s%s", scheme, domain, tsStr, hash, uri, args); } private static String genTypeCUrl(String url, String key, long ts, String hashAlgo) { Map uriInfo = splitUrl(url); String scheme = uriInfo.get("scheme"), domain = uriInfo.get("domain"), uri = uriInfo.get("uri"), args = uriInfo.get("args"); String hexts = Long.toHexString(ts); String text = String.format("%s%s%s", key, uri, hexts); String hash = getHashString(hashAlgo, text); return String.format("%s%s/%s/%s%s%s", scheme, domain, hash, hexts, uri, args); } private static String genTypeDUrl(String url, String key, String signName, String timeName, long ts, int base, String hashAlgo) { Map uriInfo = splitUrl(url); String scheme = uriInfo.get("scheme"), domain = uriInfo.get("domain"), uri = uriInfo.get("uri"), args = uriInfo.get("args"); String tsStr = String.format("%d", ts); if (base == 16) tsStr = Long.toHexString(ts); String text = String.format("%s%s%s", key, uri, tsStr); String hash = getHashString(hashAlgo, text); String authArg = String.format("%s=%s&%s=%d", signName, hash, timeName, ts); if (Objects.equals(args, "")) return String.format("%s%s%s?%s", scheme, domain, uri, authArg); else return String.format("%s%s%s%s&%s", scheme, domain, uri, args, authArg); } // GenTypeEUrl Genrate signed url by custom rule(eg.:key+domain+uri+timestamp) private static String genTypeEUrl(String url, String key, String signName, String timeName, long ts, int base, String hashAlgo) { Map uriInfo = splitUrl(url); String scheme = uriInfo.get("scheme"), domain = uriInfo.get("domain"), uri = uriInfo.get("uri"), args = uriInfo.get("args"); String tsStr = String.format("%d", ts); if (base == 16) tsStr = Long.toHexString(ts); String text = String.format("%s%s%s%s", key, domain, uri, tsStr); String hash = getHashString(hashAlgo, text); String authArg = String.format("%s=%s&%s=%s", signName, hash, timeName, tsStr); if (Objects.equals(args, "")) return String.format("%s%s%s?%s", scheme, domain, uri, authArg); else return String.format("%s%s%s%s&%s", scheme, domain, uri, args, authArg); } public static void main(String[] args) { String url = "http://www.test.com/a.txt?a=b&c=d"; String primaryKey = "primary123456"; String signName = "sign"; String tName = "t"; String uid = "0"; long ts = System.currentTimeMillis() / 1000 + 3600; // Assume requests expire in 1 hour. // long ts = 1742289420; System.out.println("OriginUrl:" + url); String[] hashAlgorithms = { "MD5", "SHA-256" }; for (String algorithm : hashAlgorithms) { System.out.printf("TypeA + %s: %s\n", algorithm, genTypeAUrl(url, primaryKey, signName, uid, ts, algorithm)); System.out.printf("TypeB + %s: %s\n", algorithm, genTypeBUrl(url, primaryKey, ts, algorithm)); System.out.printf("TypeC + %s: %s\n", algorithm, genTypeCUrl(url, primaryKey, ts, algorithm)); System.out.printf("TypeD + %s: %s\n", algorithm, genTypeDUrl(url, primaryKey, signName, tName, ts, 10, algorithm)); System.out.printf("TypeE + %s: %s\n", algorithm, genTypeEUrl(url, primaryKey, signName, tName, ts, 10, algorithm)); } } }