package net.curisit.securis.utils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; import javax.inject.Inject; import javax.inject.Singleton; import net.curisit.integrity.commons.Utils; import org.apache.commons.lang3.StringUtils; import org.jboss.resteasy.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton public class TokenHelper { private static final Logger log = LoggerFactory.getLogger(TokenHelper.class); /** * Period before token expires, set in hours. */ private static int VALID_TOKEN_PERIOD = 24; public static final String TOKEN_HEADER_PĂ€RAM = "X-SECURIS-TOKEN"; @Inject public TokenHelper() { } private static byte[] seed = "S3Cur15S33dForT0k3nG3n3r@tion".getBytes(); /** * Generate a token encoded in Base64 for user passed as parameter and taking the current moment as token timestamp * * @param user * @return */ public String generateToken(String user) { try { Date date = new Date(); String secret = generateSecret(user, date); StringBuffer sb = new StringBuffer(); sb.append(secret); sb.append(' '); sb.append(user); sb.append(' '); sb.append(Utils.toIsoFormat(date)); return Base64.encodeBytes(sb.toString().getBytes("utf-8")); } catch (NoSuchAlgorithmException e) { log.error("Error generating SHA-256 hash", e); } catch (UnsupportedEncodingException e) { log.error("Error generating SHA-256 hash", e); } return null; } private String generateSecret(String user, Date date) throws UnsupportedEncodingException, NoSuchAlgorithmException { MessageDigest mDigest = MessageDigest.getInstance("SHA-256"); mDigest.update(seed, 0, seed.length); byte[] userbytes = user.getBytes("utf-8"); mDigest.update(userbytes, 0, userbytes.length); byte[] isodate = Utils.toIsoFormat(date).getBytes(); mDigest.update(isodate, 0, isodate.length); BigInteger i = new BigInteger(1, mDigest.digest()); String secret = String.format("%1$064x", i); return secret; } /** * Check if passed token is still valid, It use to check if token is expired the attribute VALID_TOKEN_PERIOD (in hours) * * @param token * @return */ public boolean validateToken(String token) { try { String tokenDecoded = new String(Base64.decode(token)); String[] parts = StringUtils.split(tokenDecoded, ' '); String secret = parts[0]; String user = parts[1]; Date date = Utils.toDateFromIso(parts[2]); if (new Date().after(new Date(date.getTime() + VALID_TOKEN_PERIOD * 60 * 60 * 1000))) return false; String newSecret = generateSecret(user, date); return newSecret.equals(secret); } catch (IOException e) { log.error("Error decoding Base64 token", e); } catch (NoSuchAlgorithmException e) { log.error("Error generation secret to compare with", e); } return false; } public String extractUserFromToken(String token) { try { String tokenDecoded = new String(Base64.decode(token)); String[] parts = StringUtils.split(tokenDecoded, ' '); String user = parts[1]; return user; } catch (IOException e) { log.error("Error decoding Base64 token", e); } return null; } public static void main(String[] args) throws IOException { TokenHelper th = new TokenHelper(); String token = th.generateToken("pepe"); System.out.println("Token: " + token); System.out.println("Token: " + new String(Base64.decode(token))); System.out.println("Valid Token: " + th.validateToken(token)); } }