July 23rd, 2014
PSHA1 Algorithm for WS-Trust Server and Client Entropy Scenarios on Node.js
I’ve just published a new Node.js module that implements the P_SHA1
algorithm as specified in TLS spec, that is used on WS-Trust spec in scenarios where the service you want to call requires client and server entropy. It has been tested with Microsoft CRM Dynamics and ADFS.
You can find the library here https://github.com/leandrob/node-psha1
A little context
As a security feature WS-Trust
supports Proof-of-Possession Tokens. A proof-of-possession (POP) token is a security token that contains secret data that can be used to demonstrate authorized use of an associated security token, thereby the final service (relying party) can validate that the caller is the “real” owner of the token that he is presenting. Typically, although not exclusively, the POP token consist of a key known by the relying party.
WS-Trust
specifies two ways of use proof-of-possession token keys: specific and partial.
When you use specific keys, the requestor can specify the key when he requests the token or the security token service can retrieve the key in the request security token response inside of the <wst:RequestedProofToken>
. In both cases you just need to use the specific key to sign the requests you perform to the relying party (final service)
When you use partial keys, the final key, the key with which you will sign the requests you perform to the relying party must be calculated combining two keys: client key and server key.
In this scenario, also known as client and server entropy, when requesting the security token the client must specify a random key using the <wst:Entropy>
element inside of the <RequestSecurityToken>
structure, and the security token service must respond with another key, using the same element (<wst:Entropy>
) inside of the <RequestSecurityTokenResponse>
message. At the same time, the server will return a <wst:ComputedKey>
element to indicate how the final key is computed.
<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"> <t:Entropy> <t:BinarySecret>pSvudXqeURG8H0MrrKr2H+Q7nJ51WrcRJphoqcvGWu0=</t:BinarySecret> </t:Entropy> <t:RequestedProofToken> <t:ComputedKey>http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PSHA1</t:ComputedKey> </t:RequestedProofToken> </t:RequestSecurityTokenResponse>
While this can be extended, the default mechanism in WS-Trust 1.3 spec is the PSHA1 algorithm (defined in TLS spec, identified by this uri: http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PSHA1
(also http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1
is possible)
To resume, that means that both keys, client and server must be combined using the PSHA1 algoritm, and that is what this module implements.
How do I know if the service I want to consume requires client and server entropy?
That is easy, it is described in the WSDL
of the service using WS-Policy
, you will find something like this:
<sp:Trust13 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <wsp:Policy> <sp:MustSupportIssuedTokens/> <sp:RequireClientEntropy/> <sp:RequireServerEntropy/> </wsp:Policy> </sp:Trust13>
Usage
The usage is very simple, you just need to provide client key, server key, and key size.
var psha1 = require('psha1'); var key = psha1('GS5olVevYdlK4/rP8=', 'LmF9Mjf9lYMHDx376jA=', 256);
In the next post I will show how to sign a request using this key.
Hope be useful!