I'm trying to compute a key for a SOAP signature using P_SHA-1 defined by WS-Trust. The WS-Trust specification says that
key = P_SHA1 (EntropyFromRequest, EntropyFromResponse)
and the TLS spec says P_SHA-1 is
P_SHA-1(secret, seed) =
HMAC_SHA-1(secret, A(1) + seed) +
HMAC_SHA-1(secret, A(2) + seed) +
HMAC_SHA-1(secret, A(3) + seed) + ...
Where + indicates concatenation.
A() is defined as:
A(0) = seed
A(i) = HMAC_SHA-1(secret, A(i-1))
My algorithm looks like so:
- (NSData*) psha1WithSize:(int)bytes;
{
int numberOfIterations = bytes/16;
NSData *label;
NSData *secret;
NSMutableData *seed;
NSData *reqEntropy = [NSData dataWithBase64EncodedString:requestEntropy];
NSData *resEntropy = [NSData dataWithBase64EncodedString:responseEntropy];
secret = reqEntropy;
seed = resEntropy;
NSData *aIMinusOne = seed;
NSData *aI = nil;
NSMutableData *currentData = [[NSMutableData alloc] init];
for( int i=1; i <= numberOfIterations; i++ )
{
aI = [self hmacSha1Data:aIMinusOne withKey:secret];
NSMutableData *aIPlusSeed = [NSMutableData dataWithData:aI];
[aIPlusSeed appendData:seed];
[currentData appendData:[self hmacSha1Data:aIPlusSeed withKey:secret]];
aIMinusOne = aI;
aI = nil;
}
return currentData;
}
My HMAC looks like these: iPhone and HMAC-SHA-1 encoding
This doesn't seem to be working, and I can't figure out what is wrong with my algorithm. One thought I had was that the service is implemented in .NET WCF, and to get it to accept the hashed password I had to use an NSUTF16LittleEndianStringEncoding, so maybe the response entropy is in the same encoding (prior to base64 encoding)?
Any help is greatly appreciated, thanks.