Created
July 26, 2012 13:39
-
-
Save rstiller/3182073 to your computer and use it in GitHub Desktop.
Revisions
-
rstiller created this gist
Jul 26, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ package cooky; import java.io.ByteArrayOutputStream; import java.util.Arrays; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * HMAC (Key-Hashed Message Authentication Code) http://www.ietf.org/rfc/rfc2104.txt * http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf */ public class CookieEncryption { private static final SecretKey SERVER_KEY = new SecretKeySpec("MyServerPassword".getBytes(), "HmacMD5"); private static final byte SEPARATOR = (byte) ';'; protected Mac mac; protected ByteArrayOutputStream output = new ByteArrayOutputStream(); public CookieEncryption() throws Exception { mac = Mac.getInstance("HmacMD5"); } protected byte[] hmac(final SecretKey key, final byte[]... arrays) throws Exception { mac.init(key); for (byte[] array : arrays) { mac.update(array); } return mac.doFinal(); } public byte[] generateCookieValue(final byte[] username, final byte[] expiresOn, final byte[] data, final byte[] sessionKey) throws Exception { SecretKey k = new SecretKeySpec(hmac(SERVER_KEY, username, expiresOn), "HmacMD5"); byte[] encryptedData = encrypt(data, k); byte[] hash = hmac(k, username, expiresOn, data, sessionKey); output.reset(); output.write(username); output.write(SEPARATOR); output.write(expiresOn); output.write(SEPARATOR); output.write(encryptedData); output.write(SEPARATOR); output.write(hash); return output.toByteArray(); } private byte[] encrypt(final byte[] data, final SecretKey k) { // TODO: do real encryption return data; } private byte[] decrypt(final byte[] data, final SecretKey k) { // TODO: do real decryption return data; } public boolean authenticateCookieValue(final byte[] cookieValue, final byte[] sessionKey) throws Exception { int[] separators = new int[] { -1, -1, -1 }; SecretKey k; byte[] username; byte[] expiresOn; byte[] encryptedData; byte[] decryptedData; byte[] hash; byte[] cookieHash; for (int i = 0, j = 0; i < cookieValue.length; i++) { if (cookieValue[i] == SEPARATOR) { separators[j++] = i; } } username = new byte[separators[0]]; System.arraycopy(cookieValue, 0, username, 0, username.length); expiresOn = new byte[separators[1] - separators[0] - 1]; System.arraycopy(cookieValue, separators[0] + 1, expiresOn, 0, expiresOn.length); encryptedData = new byte[separators[2] - separators[1] - 1]; System.arraycopy(cookieValue, separators[1] + 1, encryptedData, 0, encryptedData.length); cookieHash = new byte[cookieValue.length - separators[2] - 1]; System.arraycopy(cookieValue, separators[2] + 1, cookieHash, 0, cookieHash.length); k = new SecretKeySpec(hmac(SERVER_KEY, username, expiresOn), "HmacMD5"); decryptedData = decrypt(encryptedData, k); hash = hmac(k, username, expiresOn, decryptedData, sessionKey); return Arrays.equals(hash, cookieHash); } }