package onlinefrontlines.auth; import java.security.*; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; /** * Helper tools for authentication * * @author jorrit * * Copyright (C) 2009-2013 Jorrit Rouwe * * This file is part of Online Frontlines. * * Online Frontlines is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Online Frontlines is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Online Frontlines. If not, see <http://www.gnu.org/licenses/>. */ public class AuthTools { /** * Convert string into byte array (discarding high bits of unicode characters) * * @param in String to convert * @return Byte array */ public static byte[] stringToByteArray(String in) { byte[] res = new byte[in.length()]; for (int i = 0; i < in.length(); ++i) res[i] = (byte)in.charAt(i); return res; } /** * Convert byte array to string * * @param in Byte array to convert * @return String value */ public static String byteArrayToString(byte[] in) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < in.length; ++i) sb.append((char)in[i]); return sb.toString(); } /** * Convert byte array to hex string * * @param in Byte array to convert * @return Hex string */ public static String byteArrayToHexString(byte[] in) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < in.length; ++i) { int d = ((int)in[i]) & 0xff; String s = Integer.toHexString(d); if (d < 0x10) sb.append("0" + s); else sb.append(s); } return sb.toString(); } /** * Convert hex string to byte array * * @param in Hex string to convert * @return Byte array */ public static byte[] hexStringToByteArray(String in) { byte[] b = new byte[in.length() / 2]; for (int i = 0; i < in.length(); i += 2) b[i / 2] = (byte)Integer.parseInt(in.substring(i, i + 2), 16); return b; } /** * Creates an 8 byte salt * * @return 16 character hex string * @throws Exception */ public static String generateSalt() throws Exception { SecureRandom r = new SecureRandom(); byte[] bytes = new byte[8]; r.nextBytes(bytes); return byteArrayToHexString(bytes); } /** * Hash a value using the HmacMD5 hash function * * @param in String to hash * @param salt The salt to use * @return Hashed value as a hex string * @throws Exception */ public static String hashHmacMD5(String in, String salt) throws Exception { Mac mac = Mac.getInstance("HmacMD5"); mac.init(new SecretKeySpec(stringToByteArray(salt), "HmacMD5")); return byteArrayToHexString(mac.doFinal(in.getBytes())); } /** * Hash a value using the MD5 hash function * * @param in Value to hash * @return Hashed value as a hex string * @throws Exception */ public static String hashMD5(String in) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); return byteArrayToHexString(md.digest(in.getBytes())); } /** * Sign text string * * @param in Text to sign * @param privateKey The private key * @return Signature as hex string * @throws Exception */ public static String sign(String in, PrivateKey privateKey) throws Exception { Signature s = Signature.getInstance("SHA1withRSA"); s.initSign(privateKey); s.update(in.getBytes()); return AuthTools.byteArrayToHexString(s.sign()); } /** * Verify signed text * * @param in Text that was signed * @param signature Signature as hex string * @param publicKey The public key * @return True if signature is valid * @throws Exception */ public static boolean verifySignature(String in, String signature, PublicKey publicKey) throws Exception { Signature v = Signature.getInstance("SHA1withRSA"); v.initVerify(publicKey); v.update(in.getBytes()); return v.verify(hexStringToByteArray(signature)); } }