You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Amit Murthy <am...@gmail.com> on 2009/08/05 20:08:59 UTC

Encrypted tokens between a non-Java back-end and java Shindig.

Hi,

I have made notes on enabling encrypted tokens between our Erlang back-end
and Java Shindig.

Would like to know if I have done it the right way.


In our model, the gadget iFrame URL is generated on the server-side and it
took me a
while to understand the secure token implementation for the Java version of
Shindig.

Here are my notes:


- Created $SRC_ROOT/config/mycontainer.js with only the following lines.

    {"gadgets.container" : ["mycontainer"],
        "gadgets.securityTokenType" : "secure",
        "gadgets.securityTokenKeyFile" : "/var/mycontainer/mycontainer.key"
    }

  Assumed that the other configuration items will be picked up from
default/container.js

- In shindig.properties (in common/conf) changed

    "shindig.containers.default=res://containers/default/container.js"
    to

"shindig.containers.default=res://containers/default/container.js,res://containers/mycontainer/mycontainer.js"


- Implemented MyContainerSecurityTokenDecoder.java (which is a copy of
DefaultSecurityTokenDecoder.java) changed to
  read the from the config for container mycontainer. Added line in
SocialApiGuiceModule.java to bind
  MyContainerSecurityTokenDecoder :

"bind(SecurityTokenDecoder.class).to(MyContainerSecurityTokenDecoder.class);"

- The iframe url generation process is as follows:
    - The Java implementation of shindig expects the token to be of format

    SecToken = "o=<Owner Id>&v=<Viewer Id>&a=<App
Id>&d=<Domain>&u=<URLEncoded gadgetURL>&m=<ModuleId>&t=<Token creation time
in epoch secs >"
        NOTE: This is different from the ":" delimited tokens used in the
BasicSecurityToken (the unencrypted one).
              Remember to URL encode the gadgetURL.

    Erlang code snippets preparing the iframe "st" url query parameter:

        %% First pad the token as per PKCS5.
        LenST = length(SecToken),
        NumPadBytes = if (LenST rem 16) == 0 -> 16; true -> 16 - (LenST rem
16) end,
        Pad = lists:foldl(fun(_N, Acc) -> list_to_binary([NumPadBytes, Acc])
end, <<"">>, lists:seq(1, NumPadBytes)),
        PaddedToken = list_to_binary([SecToken, Pad]),

        %% Encrypt using AES 128 in CBS mode and prefix the IV (generated
randomly)
        IVec = list_to_binary(lists:foldl(fun(_N, Acc) -> [(64 +
random:uniform(26)) | Acc] end, [], lists:seq(1, 16))),
        Cipher = crypto:aes_cbc_128_encrypt(AESKey, IVec, PaddedToken),
        CipherIVec = list_to_binary([IVec, Cipher]),

        %% Get a SHA MAC digest for the encrypted content, preifx and
convert entire binary to base64.
        HMACVal = crypto:sha_mac(HMACKey, CipherIVec),
        EncSecToken = "mycontainer:" ++
base64:encode_to_string(list_to_binary([CipherIVec, HMACVal])),

    NOTE: The base64 encoded token is prefixed with a "mycontainer:"

    This constitutes the "st" query parameter, i.e.,
st=url_encode(EncSecToken). Since base64 encoding contains
    "+" and "/" characters we have to once again url_encode the EncSecToken.

    I also set "synd" and "container" query parameters to "mycontainer"

    NOTE: Default token validity is 3600 seconds - defined in
    org.apache.shindig.auth.BlobCrypterSecurityToken.MAX_TOKEN_LIFETIME_SECS

    The Java implementation gets the AESKey and HMACKey keys by reading a
single MasterKey from
    the key file on disk and using function deriveKey() in
BasicBlobCrypter.java to generate
    the AESKey and HMACKey keys.

    Equivalent erlang code for the same is :

        derive_key(Type, MasterKey, Len) ->
            Base =
            if  Type == aes -> list_to_binary([<<0>>, MasterKey]);
                Type == hmac -> list_to_binary([<<1>>, MasterKey])
            end,

            Hash = crypto:sha(Base),
            if  Len == 0 -> Hash;
                true -> binary_to_list(Hash, 1, Len)
            end.


- Added resource block for mycontainer.js (so that it is copied into the
deployment war) in java/common/pom.xml.
  Look for container.js in this file and make similar entry for
mycontainer.js


Regards,
  Amit