Hi Tauren,

Shiro 1.0 and later uses an AesCipherService to perform
encryption/decryption of the cookie.  The cookie value amounts to
essentially the following (pseudo code - if you were to collapse the
relevant operations into a single method):

byte[] key = getEncryptionKeyBytes();
byte[] iv = generateSecureRandomInitializationVector(128);
byte[] serializedPrincipalCollection = jdkSerialize(subject.getPrincipals());
byte[] encrypted = encrypt(serializedPrincipalCollection, key, iv);
//I know you can't concat byte arrays in java, but this is psuedocode!:
byte[] combined = initializationVector + encrypted;
String cookieValue = Base64.encode(combined);

When the cookie is read from a request, the process is reversed:

byte[] combined = Base64.decrypt(cookieValue);
//The first 128 bits (16 bytes) are the prepended IV:
byte[] iv = combined[0]..combined[15];
//The remaining is the actual encrypted data:
byte[] encrypted = combined[16]..combined[combined.length-1];
byte[] serializedPrincipals = decrypt(encrypted, key, iv);
PrincipalCollection principals = jdkDeserialize(serializedPrincipals);

In Shiro 1.1.0, the AesCipherService's default settings for byte array
encryption were:

Key size: 128 (bits)
Block size: 128 (bits)
Mode of operation: CFB
Padding scheme: PKCS5
Initialization Vector size: 128 (bits)
Autogenerate and prefix IVs: true

In Shiro 1.2.0+, the default settings are the same except for the Mode
of Operation.  In Shiro 1.2+, the mode of operation is CBC.  (This
change was mentioned in the 1.2.0 release notes:
http://svn.apache.org/repos/asf/shiro/trunk/RELEASE-NOTES).

HTH!

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
Stormpath wins GigaOM Structure Launchpad Award! http://bit.ly/MvZkMk

On Sun, Jan 13, 2013 at 4:38 PM, Tauren Mills <[email protected]> wrote:
> I'm trying to figuring out how to decrypt a Shiro rememberMe cookie using
> javascript running in a node.js/express.js server app. If anyone has been
> down this path or has any advice of any sort, please let me know!
>
> I'd like to extract identity principals from the rememberMe cookie once I'm
> able to decrypt it. I assume this is available, but what exactly is stored
> in the rememberMe cookie?
>
> How is the rememberMe cookie encrypted? Does it use an AES cipher and then
> Base64 encode it?  Is padding used, what type? What about string encoding
> ('utf8', ascii', etc)? There seem to be lots of combinations and figuring
> out the right one is daunting.
>
> I'm currently using Shiro 1.1.0. I've been looking at the following
> resources but don't haven't solved it yet:
>
> http://stackoverflow.com/questions/10548973/encrypting-and-decrypting-with-python-and-nodejs
> http://stackoverflow.com/questions/12685475/encrypt-in-java-decrypt-in-node-js
> http://stackoverflow.com/questions/11477175/encrypting-and-decrypting-data-through-transport-through-java-to-node-js
>
> Here's some config info if it helps:
>
>    <bean id="securityManager"
> class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
>         <property name="cacheManager" ref="cacheManager"/>
>         <property name="realm" ref="myRealm"/>
>         <property name="sessionMode" value="native"/>
>         <property name="rememberMeManager" ref="myRememberMeManager"/>
>     </bean>
>
>     <bean name="myRememberMeManager"
> class="com.myapp.security.MyRememberMeManager">
>      <property name="cipherKey" ref="cipherKeyBytes"/>
> <property name="cookie.domain" value="${global.cookieDomain}"/>
> <property name="cookie.path" value="/"/>
>     </bean>
> <bean id="cipherKeyBytes"
> class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
> <property name="targetClass" value="org.apache.shiro.codec.Base64"/>
> <property name="targetMethod" value="decode"/>
> <property name="arguments">
> <list>
> <value>mySecretValue</value>
> </list>
> </property>
> </bean>
>
> Thanks!
> Tauren
>

Reply via email to