Created
July 26, 2012 13:39
-
-
Save rstiller/3182073 to your computer and use it in GitHub Desktop.
SecureCookie impl.
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 characters
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment