Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OAuth signature with RSA-SHA1 on iOS

I need help creating an RSA-SHA1 signature to be used in a 3-legged OAuth implementation on iOS.

I was able to do this using HMAC-SHA1 using CommonCrypto.h, but this library doesn't seem to support RSA-SHA1.

Have any of you implemented OAuth signatures with RSA? Could you point me to some resources where I can find more information?

Thanks.

like image 573
Erik Villegas Avatar asked Dec 01 '22 19:12

Erik Villegas


2 Answers

The answer by Erik Villegas was also the solution for me. But there is a bug in the posted code which I encountered when using this solution: secretFile was opened with fopen(), so it must be closed with fclose()

- (NSString *)RSASHA1HashForString:(NSString *)source {

    NSLog(@"encrypting %@", source);

    if (source == nil) return nil;

    OpenSSL_add_all_algorithms();

    NSString *signature = nil;

    // make a SHA-1 digest of the source string
    const char* sourceChars = [source UTF8String];

    unsigned char digest[SHA_DIGEST_LENGTH];
    SHA1((const unsigned char *)sourceChars, strlen(sourceChars), digest);

    NSString *path = [[NSBundle mainBundle] pathForResource:@"privatekey" ofType:@"pem"];

    const char *pathCString = [path cStringUsingEncoding:NSUTF8StringEncoding];
    FILE *secretFile = fopen(pathCString, "r");

    RSA *rsa = NULL;
    PEM_read_RSAPrivateKey(secretFile, &rsa, NULL, NULL);


    if (rsa != NULL) {

        unsigned int sigLen = 0;
        unsigned char *sigBuff = malloc(RSA_size(rsa));

        int result = RSA_sign(NID_sha1, digest, (unsigned int) sizeof(digest),
                              sigBuff, &sigLen, rsa);

        if (result != 0) {
            NSData *sigData = [NSData dataWithBytes:sigBuff length:sigLen];
            signature = [self base64forData:sigData];
        }

        free(sigBuff);

        RSA_free(rsa);
    }

    fclose(secretFile);

    NSLog(@"generated signature: %@", signature);

    return signature;
}
like image 67
Andreas Bauer Avatar answered Dec 15 '22 05:12

Andreas Bauer


I finally found the solution. Here is a method that will look for a privatekey.pem file in your bundle and create a RSA-SHA1 signature using the string that is passed in. You will need to add the openssl library. You can use this project as a reference: https://github.com/x2on/OpenSSL-for-iPhone

- (NSString *)RSASHA1HashForString:(NSString *)source {

    NSLog(@"encrypting %@", source);

    if (source == nil) return nil;

    OpenSSL_add_all_algorithms();

    NSString *signature = nil;

    // make a SHA-1 digest of the source string
    const char* sourceChars = [source UTF8String];

    unsigned char digest[SHA_DIGEST_LENGTH];
    SHA1((const unsigned char *)sourceChars, strlen(sourceChars), digest);

    NSString *path = [[NSBundle mainBundle] pathForResource:@"privatekey" ofType:@"pem"];

    const char *pathCString = [path cStringUsingEncoding:NSUTF8StringEncoding];
    FILE *secretFile = fopen(pathCString, "r");

    RSA *rsa = NULL;
    PEM_read_RSAPrivateKey(secretFile, &rsa, NULL, NULL);


    if (rsa != NULL) {

        unsigned int sigLen = 0;
        unsigned char *sigBuff = malloc(RSA_size(rsa));

        int result = RSA_sign(NID_sha1, digest, (unsigned int) sizeof(digest),
                              sigBuff, &sigLen, rsa);

        if (result != 0) {
            NSData *sigData = [NSData dataWithBytes:sigBuff length:sigLen];
            signature = [self base64forData:sigData];
        }

        free(sigBuff);

        RSA_free(rsa);
    }

    NSLog(@"generated signature: %@", signature);

    return signature;
}

If you are implementing OAuth you'll need to pass the signature base into this method. More info can be found here: http://oauth.net/core/1.0a/#anchor13

like image 34
Erik Villegas Avatar answered Dec 15 '22 03:12

Erik Villegas