You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Tauren Mills <ta...@groovee.com> on 2013/01/14 01:38:56 UTC

Decrypt shiro rememberMe cookie in node.js

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

Re: Decrypt shiro rememberMe cookie in node.js

Posted by Tauren Mills <ta...@tauren.com>.
I forgot to report back previously, but I was able to get this working. I
posted details in my blog:
http://tauren.com/2013/01/decrypt-java-shiro-rememberme-cookie-in-node-js-express-app/

Maybe this will prove helpful to someone in the future. I'm certainly open
to any improvements or suggestions.

Thanks for all the help Les!

Tauren






On Tue, Jan 15, 2013 at 9:21 AM, Les Hazlewood <lh...@apache.org>wrote:

>
> Basically, all I need is some way to extract the user name or user ID from
>> the cookie. The output above should contain the ID number 1834 somewhere,
>> but I really don't want to write a Java object deserializer in Javascript!
>> (Although, if I did, this might be useful:
>> http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html
>>  )
>>
>> Any suggestions? I don't think writing a custom Serializer that only
>> saves the User ID would work, since Shiro is expecting to deserialize the
>> entire PrincipalsCollection data.
>>
>
> Hi Tauren,
>
> Shiro does not use its XMLSerializer by default because the XMLSerializer
> _only_ serializes/deserializes JavaBean object graphs - i.e. every object
> has a default no-arg constructor and public getter/setters to read/set
> properties (it uses the java.beans.XMLEncoder and java.beans.XMLDecoder
> classes in its implementation).
>
> Since Shiro can't know if the objects in a PrincipalCollection are all
> guaranteed to be beans, it defaults to the DefaultSerializer, which will
> work in any Java environment (i.e. it's 'safer' as a default).
>
> But that doesn't mean you can't use it.  If you can be assured that every
> object you (or your realms) adds to the PrincipalCollection is a bean (or I
> think a primitive), the XMLSerializer will work fine.
>
> But if for some reason that won't work, then the best bet is to create a
> Serializer implementation for which you have a parallel implementation in
> JavaScript (this is after all why we created a separate interface for this
> instead of hard-coding serialization logic in the RememberMeManager
> implementation ;)).
>
> HTH,
>
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
> Stormpath wins GigaOM Structure Launchpad Award! http://bit.ly/MvZkMk
>

Re: Decrypt shiro rememberMe cookie in node.js

Posted by Les Hazlewood <lh...@apache.org>.
> Basically, all I need is some way to extract the user name or user ID from
> the cookie. The output above should contain the ID number 1834 somewhere,
> but I really don't want to write a Java object deserializer in Javascript!
> (Although, if I did, this might be useful:
> http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html
>  )
>
> Any suggestions? I don't think writing a custom Serializer that only saves
> the User ID would work, since Shiro is expecting to deserialize the entire
> PrincipalsCollection data.
>

Hi Tauren,

Shiro does not use its XMLSerializer by default because the XMLSerializer
_only_ serializes/deserializes JavaBean object graphs - i.e. every object
has a default no-arg constructor and public getter/setters to read/set
properties (it uses the java.beans.XMLEncoder and java.beans.XMLDecoder
classes in its implementation).

Since Shiro can't know if the objects in a PrincipalCollection are all
guaranteed to be beans, it defaults to the DefaultSerializer, which will
work in any Java environment (i.e. it's 'safer' as a default).

But that doesn't mean you can't use it.  If you can be assured that every
object you (or your realms) adds to the PrincipalCollection is a bean (or I
think a primitive), the XMLSerializer will work fine.

But if for some reason that won't work, then the best bet is to create a
Serializer implementation for which you have a parallel implementation in
JavaScript (this is after all why we created a separate interface for this
instead of hard-coding serialization logic in the RememberMeManager
implementation ;)).

HTH,

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

Re: Decrypt shiro rememberMe cookie in node.js

Posted by Tauren Mills <ta...@tauren.com>.
Les,

Thanks, that was tons of help!  I'm seeing Java class names decrypted now,
so I think decryption is working. Here's the javascript code to run in
node.js:

    var decrypt = function (input, password, callback) {
        // Decode input from base64 to binary string
        var decoded = new Buffer(input, 'base64').toString('binary');

        // The first 128 bits (16 bytes) are the prepended IV
        var iv = decoded.slice(0,16);

        // The remaining is the actual encrypted data
        var data = decoded.slice(16);

        // Decode password from Base64
        var key = new Buffer(password, 'base64').toString('binary');

        // Decipher encrypted data
         var decipher = crypto.createDecipheriv('aes-128-cfb', key, iv);
        decipher.setAutoPadding(false);
        var decrypted = decipher.update(data, 'binary') +
decipher.final('binary');
        var plaintext = new Buffer(decrypted, 'binary').toString('ascii');

        // Return decrypted text
        callback(plaintext);
    };

    var key = 'UaNG2oxPGFh1kC4QS0/1Rw==';

    // Real rememberMe for 'testuser' using key on development environment
using DefaultSerializer
    var rememberMe =
'jVIfq39P7KmDZDEI5vY7+wlhe0dA2J7wd5Sak9AIeVXfuyB6KtGNMIg3LLNLELhQ7BjaO+k5XjoHX7CepC3+YeP9/s4F+dZcfs69UMLZEo1rk1knf/bXK3/90q2ksVQuIVFVtKy0OYU22f1eQX01SHw6btK2sZ+WBmFNDYzJAcX2kSTgENgIqSrRqH/W9ora1NaOlxKy5+VKs7qU1AocLUmoO5AKqg3EaXs99PjykzadD8Wc/kCIz5tBmpQbxjC/By7f7Aqs7U2nxxkzXo68TTDLtZu4u4XhcVvk7+goCWYZT35zN3pWkoOLiMsy4pH5DVRnaOEdCE4NGUKOnomcrvEdChkZoNE+Q7FYPBtz1mEf5EXsNOOl5iAa2etVbmN9VtWDlfsvOCKq2KHBcR+EWYILOEFAGjEUKWS6pz0ISKl8ftqX8LC3E/m3t4aAJMRIWXdf+K6EQ8EYbAfVjRC0xnDRzmAHxdF5RHj27vQI14znuvOg8oynoj/5TliOq3xxpzUdgnCbxQBEquqDC4IO8Wpaftm7NZt/b/KP6+jo7NNXqoliicgsc0iaHc7PVkny9Xrp34Da5lUS3UFaJLGHAQ==';

    decrypt(rememberMe, key, function(output) {
        console.log(output);
    });

    console.log('-------------------------------------');

    // XMLSerializer based rememberMe
    var xmlRememberMe =
'X1UyjjAxJVxryO9kAVjj9WZ3Y4gPvz1daS8MryTC3rXcw7EhFare4/7kG1Y4ojkLK7hV8tjn/z5M9T0YmFaqBJjjhCPEn0ty860vI0HDCrhY++rR+L21Q1SVkJ5CRPEiD4PP5tgy2dTiGcrv1VvI0Lwm7uFA72bHp796xqWbW/NdKYicdWDkFH0zVwOxXF6dfCyCjME1nd2UzOl76hmJDVpkJqkkj9GmtAetbB6Muk+ySKkeK+Dc7KrVCBXnS0B0yB5MIoDFqjpq1e28BDADEQ==';

    decrypt(xmlRememberMe, key, function(output) {
        console.log(output);
    });

However, it looks like the payload is a byte array of Java serialization
data. This isn't terribly useful, as you can see:

��sr2org.apache.shiro.subject.SimplePrincipalCollection�X%JLrealmPrincipalstLjava/util/Map;xpsrjava.util.LinkedHashMap4�N\l��Z


accessOrderxrjava.util.HashMap���`�F
loadFactorI thresholdxp?@
                             t
SprtzRealmsrjava.util.LinkedHashSet�l�Z��*xrjava.util.HashSet�D�����4xpw

?@srjava.lang.Long;���̏#�Jvaluexrjava.lang.Number���

                                               ���xp*xxwq~x

So I've been messing around configuring my RememberMeManager to use the
XMLSerializer instead. I configure it in Spring like this:

    <bean id="xmlSerializer" class="org.apache.shiro.io.XmlSerializer">
    </bean>

    <bean name="sportZingRememberMeManager"
class="com.sprtz.security.SportZingRememberMeManager">
     <property name="cipherKey" ref="cipherKeyBytes"/>
<property name="cookie.domain" value="${global.cookieDomain}"/>
        <property name="cookie.path" value="/"/>
        <property name="serializer" ref="xmlSerializer"/>
    </bean>

It looks like it is using it, because if I put a breakpoint in
getRememberedPrinciplals, this.serializer is an instance of XMLSerializer:

public class SportZingRememberMeManager extends CookieRememberMeManager {
 private static final Logger log =
LoggerFactory.getLogger(SportZingRememberMeManager.class);
private MemberService memberService;

       @Autowired
public void setMemberService(MemberService memberService) {
 this.memberService = memberService;
 }

@Override
 public PrincipalCollection getRememberedPrincipals(SubjectContext
subjectContext) {
 PrincipalCollection principals =
super.getRememberedPrincipals(subjectContext);

 if ( principals != null ) {
 Long id = (Long) principals.getPrimaryPrincipal();
memberService.updateAccessed(id);
 }
 return principals;
}
}

However, if I decrypt the rememberMe cookie that was generated this way, it
still contains garbage and classnames and doesn't look like XML. Plus,
calling super.getRememberedPrincipals() always returns an empty object, so
rememberme features aren't working.

Basically, all I need is some way to extract the user name or user ID from
the cookie. The output above should contain the ID number 1834 somewhere,
but I really don't want to write a Java object deserializer in Javascript!
(Although, if I did, this might be useful:
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html
 )

Any suggestions? I don't think writing a custom Serializer that only saves
the User ID would work, since Shiro is expecting to deserialize the entire
PrincipalsCollection data. Any idea why the XMLSerializer wouldn't decrypt
to XML and the serialization wouldn't work?

Thanks,
Tauren




On Mon, Jan 14, 2013 at 2:15 PM, Les Hazlewood <lh...@apache.org>wrote:

> P.S. Shiro defaults all String encoding to UTF-8.
>
> On Mon, Jan 14, 2013 at 2:02 PM, Les Hazlewood <lh...@apache.org>
> wrote:
> > 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 <ta...@groovee.com>
> 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
> >>
>

Re: Decrypt shiro rememberMe cookie in node.js

Posted by Les Hazlewood <lh...@apache.org>.
P.S. Shiro defaults all String encoding to UTF-8.

On Mon, Jan 14, 2013 at 2:02 PM, Les Hazlewood <lh...@apache.org> wrote:
> 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 <ta...@groovee.com> 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
>>

Re: Decrypt shiro rememberMe cookie in node.js

Posted by Les Hazlewood <lh...@apache.org>.
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 <ta...@groovee.com> 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
>