Unsolved

This post is more than 5 years old

3347

April 13th, 2010 04:00

Signature mismatch

I'm trying to work with Atmos Online from Ruby, however I keep getting

\n\n\t1032\n\tThere was a mismatch between the signature in the request and the signature computed by the server.\n

Here's a piece of code that I use: http://pastie.org/private/umdngkhbtiolctps8jn60q

Is there a way to debug the problem? Maybe, someone has some code to share?

Thanks!

2 Intern

 • 

212 Posts

April 14th, 2010 20:00

Hi Chuck,

Its typically the signature generation that causes problems. Here is some objective c code that works - maybe you could translate to ruby. Also, all the bindings have signature generation code too. Here is a link to Java binding source code that you can browse online - http://codesearch.developer.emc.com/kse/entcodespaces/EGrbkn

One thing I did notice was, the x-emc headers were not sorted -


-(void) signRequest:(NSMutableURLRequest *) request withSharedSecret:(NSString *)sharedSecret forResource:(NSString *) resource {

     

     NSDictionary *headers = [request allHTTPHeaderFields];

     NSArray *keys = [headers allKeys];

     NSMutableArray *emcKeys = [[NSMutableArray alloc] init];

     for(int i=0;i count;i++) {

          NSString *strKey = (NSString *) [keys objectAtIndex:i];

          

          //NSLog(@"header %@",strKey);

          if([[strKey lowercaseString] hasPrefix:@"x-emc-"]) {

               [emcKeys addObject:strKey];

          }

     }

     NSArray *sortedEmcKeys = [emcKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

     

     //HTTP Method

     NSMutableString *signStr = [[NSMutableString alloc] init];

     [signStr appendString:request.HTTPMethod];

     [signStr appendString:@"\n"];

     

     //Content-Type

     NSString *contentTypeVal = [headers objectForKey:@"Content-Type"];

     if(contentTypeVal != nil) {

          [signStr appendString:contentTypeVal];

     }

     [signStr appendString:@"\n"];

     

     //Range

     NSString *rangeVal = [headers objectForKey:@"Range"];

     if(rangeVal != nil) {

          [signStr appendString:rangeVal];

     }

     [signStr appendString:@"\n"];

     

     //Date must exist since its a required field. TODO - check for non-existence of data in future

     [signStr appendString:(NSString *)[headers objectForKey:@"Date"]];

     [signStr appendString:@"\n"];

     

     //append resource

     [signStr appendString:[resource lowercaseString]];

     [signStr appendString:@"\n"];

     

     for(int i=0;i < sortedEmcKeys.count;i++) {

          [signStr appendString:[[sortedEmcKeys objectAtIndex:i] lowercaseString]];

          [signStr appendString:@":"];

          NSString *trimmedStr = [[headers objectForKey:[sortedEmcKeys objectAtIndex:i]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

          NSString *nlReplaced1 = [trimmedStr stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];

          NSString *nlReplaced2 = [nlReplaced1 stringByReplacingOccurrencesOfString:@"\n" withString:@""];

          NSString *nlReplaced3 = [nlReplaced2 stringByReplacingOccurrencesOfString:@"\r" withString:@""];

          [signStr appendString:nlReplaced3];

          if(i < (sortedEmcKeys.count -1)) {

               [signStr appendString:@"\n"];

          }

     }

     

     NSData *keyData = [NSData dataWithBase64EncodedString:sharedSecret];

     NSData *clearTextData = [signStr dataUsingEncoding:NSUTF8StringEncoding];

     

     uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};

     

     CCHmacContext hmacContext;

     CCHmacInit(&hmacContext, kCCHmacAlgSHA1, keyData.bytes, keyData.length);

     CCHmacUpdate(&hmacContext, clearTextData.bytes, clearTextData.length);

     CCHmacFinal(&hmacContext, digest);

     

     NSData *out = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];

     NSString *base64Enc = [out base64Encoding];

     //NSLog(@"signStr from method %@",signStr);

     //NSLog(@"Base 64 sig from method: %@",base64Enc);

     

     [request setValue:base64Enc forHTTPHeaderField:@"x-emc-signature"];

     

     [emcKeys release];

     [signStr release];

     

}

April 15th, 2010 02:00

x-emc headers are not sorted in request body, however, i call #sort method when calculate signature.

The most interesting thing is that, when i fill in headers with test data from AoL-Pgm book (API reference), and substitute my UID and SECRET_KEY in params — signature hash is calculated correctly, which means, signature algorithm works correctly.

P.S. I have updated the pastie with a better code.

2 Intern

 • 

212 Posts

April 15th, 2010 08:00

Hi Chuck,

It looks like your code is requesting all objects using /rest/objects. Maybe you want to filter that request by specifying a listable tag.

I have a feeling that it might be failing because there is nothing to filter the objects returned to avoid sending back ALL objects. Try including a x-emc-tags header.

Aashish

April 15th, 2010 09:00

Solved.

Managed to get it working. If anyone will run into an issue or will be lazy enough to implement that, ping me http://github.com/bai and I will share some code.

Thank you!

No Events found!

Top