From 091c6af2a0f232600981b10214b925706a859a37 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 11 May 2020 18:28:05 +0200 Subject: [PATCH] Hash/Cookie utils --- CookieUtils.java | 57 +++++++++++++++++++++++++++++++ HashUtils.java | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ StringUtils.java | 3 ++ 3 files changed, 149 insertions(+) create mode 100644 CookieUtils.java create mode 100644 HashUtils.java diff --git a/CookieUtils.java b/CookieUtils.java new file mode 100644 index 0000000..f082026 --- /dev/null +++ b/CookieUtils.java @@ -0,0 +1,57 @@ +package be.nikiroo.utils; + +import java.util.Date; + +public class CookieUtils { + /** + * The number of seconds for the period (we accept the current or the + * previous period as valid for a cookie, via "offset"). + */ + static public int GRACE_PERIOD = 3600 * 1000; // between 1 and 2h + + /** + * Generate a new cookie value from the user (email) and an offset. + *

+ * You should use an offset of "0" when creating the cookie, and an offset + * of "0" or "-1" if required when checking for the value (the idea is to + * allow a cookie to persist across two timespans; if not, the cookie will + * be expired the very second we switch to a new timespan). + * + * @param value + * the value to generate a cookie for -- you must be able to + * regenerate it in order to check it later + * @param offset + * the offset (should be 0 for creating, 0 then -1 if needed for + * checking) + * + * @return the new cookie + */ + static public String generateCookie(String value, int offset) { + long unixTime = (long) Math.floor(new Date().getTime() / GRACE_PERIOD) + + offset; + return HashUtils.sha512(value + Long.toString(unixTime)); + } + + /** + * Check the given cookie. + * + * @param value + * the value to generate a cookie for -- you must be able to + * regenerate it in order to check it later + * @param cookie + * the cookie to validate + * + * @return TRUE if it is correct + */ + static public boolean validateCookie(String value, String cookie) { + if (cookie != null) + cookie = cookie.trim(); + + String newCookie = generateCookie(value, 0); + if (!newCookie.equals(cookie)) { + newCookie = generateCookie(value, -1); + } + + return newCookie.equals(cookie); + } +} diff --git a/HashUtils.java b/HashUtils.java new file mode 100644 index 0000000..df8d7c6 --- /dev/null +++ b/HashUtils.java @@ -0,0 +1,89 @@ +package be.nikiroo.utils; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Small class to easily hash some values in a few different ways. + *

+ * Does not handle the salt itself, you have to add it yourself. + * + * @author niki + */ +public class HashUtils { + /** + * Hash the given value. + * + * @param value + * the value to hash + * + * @return the hash that can be used to confirm a value + * + * @throws RuntimeException + * if UTF-8 support is not available (!) or SHA-512 support is + * not available + * @throws NullPointerException + * if email or pass is NULL + */ + static public String sha512(String value) { + return hash("SHA-512", value); + } + + /** + * Hash the given value. + * + * @param value + * the value to hash + * + * @return the hash that can be used to confirm the a value + * + * @throws RuntimeException + * if UTF-8 support is not available (!) or MD5 support is not + * available + * @throws NullPointerException + * if email or pass is NULL + */ + static public String md5(String value) { + return hash("MD5", value); + } + + /** + * Hash the given value. + * + * @param algo + * the hash algorithm to use ("MD5" and "SHA-512" are supported) + * @param value + * the value to hash + * + * @return the hash that can be used to confirm a value + * + * @throws RuntimeException + * if UTF-8 support is not available (!) or the algorithm + * support is not available + * @throws NullPointerException + * if email or pass is NULL + */ + static private String hash(String algo, String value) { + try { + MessageDigest md = MessageDigest.getInstance(algo); + md.update(value.getBytes("UTF-8")); + byte byteData[] = md.digest(); + + StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < byteData.length; i++) { + String hex = Integer.toHexString(0xff & byteData[i]); + if (hex.length() % 2 == 1) + hexString.append('0'); + hexString.append(hex); + } + + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(algo + " hashing not available", e); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException( + "UTF-8 encoding is required in a compatible JVM", e); + } + } +} diff --git a/StringUtils.java b/StringUtils.java index b3c1071..be1c654 100644 --- a/StringUtils.java +++ b/StringUtils.java @@ -454,7 +454,10 @@ public class StringUtils { * the input data * * @return the hash + * + * @deprecated please use {@link HashUtils} */ + @Deprecated static public String getMd5Hash(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); -- 2.27.0