Below is my attempt to decrypt the cookie. The code includes a real cookie and the key that was used to encrypt it. So it should be able to be decrypted.
var decrypt = function (input, password, callback) {
// Convert input from base64 to binary string
var edata = new Buffer(input, 'base64').toString('binary');
// Decode password from Base64
var key = new Buffer(password, 'base64').toString('binary');
// Decipher encrypted data
var decipher = crypto.createDecipher('aes-128-cbc', key);
var decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
var plaintext = new Buffer(decrypted, 'binary').toString('utf8');
// Return decrypted text
callback(plaintext);
};
// Real rememberMe for 'testuser' using key on development environment
var rememberMe = 'jVIfq39P7KmDZDEI5vY7+wlhe0dA2J7wd5Sak9AIeVXfuyB6KtGNMIg3LLNLELhQ7BjaO+k5XjoHX7CepC3+YeP9/s4F+dZcfs69UMLZEo1rk1knf/bXK3/90q2ksVQuIVFVtKy0OYU22f1eQX01SHw6btK2sZ+WBmFNDYzJAcX2kSTgENgIqSrRqH/W9ora1NaOlxKy5+VKs7qU1AocLUmoO5AKqg3EaXs99PjykzadD8Wc/kCIz5tBmpQbxjC/By7f7Aqs7U2nxxkzXo68TTDLtZu4u4XhcVvk7+goCWYZT35zN3pWkoOLiMsy4pH5DVRnaOEdCE4NGUKOnomcrvEdChkZoNE+Q7FYPBtz1mEf5EXsNOOl5iAa2etVbmN9VtWDlfsvOCKq2KHBcR+EWYILOEFAGjEUKWS6pz0ISKl8ftqX8LC3E/m3t4aAJMRIWXdf+K6EQ8EYbAfVjRC0xnDRzmAHxdF5RHj27vQI14znuvOg8oynoj/5TliOq3xxpzUdgnCbxQBEquqDC4IO8Wpaftm7NZt/b/KP6+jo7NNXqoliicgsc0iaHc7PVkny9Xrp34Da5lUS3UFaJLGHAQ==';
var key = 'UaNG2oxPGFh1kC4QS0/1Rw==';
decrypt(rememberMe, key, function(output) {
console.log(output);
});
When this code is run, I get the following error:
/Users/tauren/temp/crypto.js:140
var decrypted = decipher.update(edata, 'binary') + decipher.final('bin
^
TypeError: DecipherFinal fail
at decrypt (/Users/tauren/temp/crypto.js:140:69)
at Object.<anonymous> (/Users/tauren/temp/crypto.js:151:5)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
By looking at the Shiro code, it appears they do the following to create the cookie:
- Serialize the unencrypted value to a byte array
- Encrypt the byte array using the AES cipher with a key generated by the AesCipherService
- Base64 encode the encrypted byte array
I'm trying to the the reverse, but something must be missing. Here's some things I'm unsure about:
- The AES cipher is used in the java code, but which cipher is equivalent in node?. Is it aes-256-cbc, aes-128-cbc, aes-128-ecb, etc?
- Should I be using crypto.createDecipher or crypto.createDecipheriv (with IV at end)?
- I'm unsure if I need to be dealing with padding (PKCS?)
- What about string encoding ('utf8', 'ascii', etc.)?
- What about salts?