62 votes

Exemple de code Objective-C pour HMAC-SHA1

J'ai besoin de générer HMAC-SHA1 dans Objective C. Mais je n'ai rien trouvé qui fonctionne. J'ai essayé avec CommonCrypto, en utilisant CCHMAC, mais ne fonctionnait pas. J'ai besoin de générer un hmac et après générer le numéro HOTP.

Quelqu'un a un exemple de code en Objective C ou C?

72voto

Can Berk Güder Points 39887

Voici comment générer un HMAC à l'aide de SHA-256:

 NSString *key;
NSString *data;

const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];

unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                      length:sizeof(cHMAC)];

NSString *hash = [HMAC base64Encoding];
 

Je ne connais pas de bibliothèque HOTP, mais l'algorithme était assez simple, si je me souviens bien.

38voto

Zivic Sanel Points 266

voici comment vous pouvez générer des HMAC-SHA1 base64.

Vous devez ajouter Base64.h et en Base64.m à votre projet. Vous pouvez l'obtenir à partir d' ici.

Si vous utilisez un ARC, il va montrer quelques erreurs en Base64.m. Trouver les lignes qui sont similaires comme ceci

return [[[self alloc] initWithBase64String:base64String] autorelease];

ce que vous avez besoin est de supprimer l'autorelease section. Le résultat final devrait ressembler à:

return [[self alloc] initWithBase64String:base64String];

Maintenant, dans votre projet général d'importation "Base64.h" et le code suivant

#import "Base64.h"
#include <CommonCrypto/CommonDigest.h>
#include <CommonCrypto/CommonHMAC.h>

- (NSString *)hmacsha1:(NSString *)data secret:(NSString *)key {

    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];

    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

    NSString *hash = [HMAC base64String];

    return hash;
}

Avec

NSLog(@"Hash: %@", hash);  

vous obtiendrez quelque chose de similaire à ceci:

ghVEjPvxwLN1lBi0Jh46VpIchOc=

 

22voto

codeplasma Points 329

C'est la solution complète qui fonctionne sans bibliothèque supplémentaire ni hacks:

 +(NSString *)hmac:(NSString *)plaintext withKey:(NSString *)key
{
    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [plainText cStringUsingEncoding:NSASCIIStringEncoding];

    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMACData = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

    const unsigned char *buffer = (const unsigned char *)[HMACData bytes];
    NSString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2];

    for (int i = 0; i < HMACData.length; ++i)
        HMAC = [HMAC stringByAppendingFormat:@"%02lx", (unsigned long)buffer[i]];

    return HMAC;
}
 

Il n'est pas nécessaire d'inclure une bibliothèque tierce tierce tierce, car celle-ci est déjà codée.

8voto

primulaveris Points 123

Cela fonctionne sans utiliser de protocoles personnalisés, en utilisant du code de http://cocoawithlove.com/2009/07/hashvalue-object-for-holding-md5-and.html

HashSHA256.h

 #import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>

@interface HashSHA256 : NSObject {


}

 - (NSString *) hashedValue :(NSString *) key andData: (NSString *) data ; 

@end
 

HashSHA256.m

 #import "HashSHA256.h"

#import <CommonCrypto/CommonHMAC.h>


@implementation HashSHA256


- (NSString *) hashedValue :(NSString *) key andData: (NSString *) data {


    const char *cKey  = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding];
    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSString *hash;

    NSMutableString* output = [NSMutableString   stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", cHMAC[i]];
    hash = output;
    return hash;

}

@end
 

Usage:

 - (NSString *) encodePassword: (NSString *) myPassword {
    HashSHA256 * hashSHA256 = [[HashSHA256 alloc] init];   
    NSString * result = [hashSHA256 hashedValue:mySecretSalt andData:myPassword];       
    return result;       
}
 

2voto

Neco Points 11

Voici comment vous le faites sans fichiers externes renvoyant une chaîne hexagonale:

 -(NSString *)hmac:(NSString *)plaintext withKey:(NSString *)key
{
    const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [plaintext cStringUsingEncoding:NSASCIIStringEncoding];
    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)];
    const unsigned char *buffer = (const unsigned char *)[HMACData bytes];
    NSMutableString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2];
    for (int i = 0; i < HMACData.length; ++i){
        [HMAC appendFormat:@"%02x", buffer[i]];
     }
   return HMAC;
}
 

Il a été testé dans xCode 5 avec iOS 7 et fonctionne bien!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: