在iOS上使用RSA-SHA1进行OAuth签名

Eri*_*gas 4 iphone cryptography rsa objective-c ios

我需要帮助创建一个RSA-SHA1签名,以便在iOS上的三脚OAuth实现中使用.

我能够使用CommonCrypto.h使用HMAC-SHA1执行此操作,但此库似乎不支持RSA-SHA1.

你们有没有用RSA实现OAuth签名?你能指点我一些可以找到更多信息的资源吗?

谢谢.

小智 13

Erik Villegas的答案也是我的解决方案.但是在使用此解决方案时遇到的已发布代码中存在一个错误:secretFile已打开fopen(),因此必须关闭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;
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*gas 5

我终于找到了解决方案.下面是一个方法,它将在bundle中查找privatekey.pem文件,并使用传入的字符串创建RSA-SHA1签名.您需要添加openssl库.您可以将此项目用作参考: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;
}
Run Code Online (Sandbox Code Playgroud)

如果要实施OAuth,则需要将签名库传递给此方法.更多信息可以在这里找到:http://oauth.net/core/1.0a/#anchor13

  • 这个答案缺少fclose(fp)调用,因此代码泄漏了文件句柄. (7认同)