Skip to content

Instantly share code, notes, and snippets.

@rstiller
Created July 26, 2012 13:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rstiller/3182073 to your computer and use it in GitHub Desktop.
Save rstiller/3182073 to your computer and use it in GitHub Desktop.
SecureCookie impl.
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