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