it-swarm.com.de

Objective-C-Beispielcode für HMAC-SHA1

Ich muss HMAC-SHA1 in Objective C generieren. Aber ich habe nichts gefunden, was funktioniert. Ich habe es mit CommonCrypto unter Verwendung von CCHMAC versucht, aber es hat nicht funktioniert. Ich muss ein hmac generieren und danach eine HOTP-Nummer generieren.

Hat jemand einen Beispielcode in Objective C oder C?

62
Helena

So generieren Sie einen HMAC mit 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];

Ich kenne keine HOTP-Bibliothek, aber der Algorithmus war recht einfach, wenn ich mich richtig erinnere.

72
Can Berk Güder

so können Sie HMAC-SHA1 base64 generieren.

Sie müssen Base64.h und Base64.m zu Ihrem Projekt hinzufügen. Sie können es von hier bekommen.

Wenn Sie ARC verwenden, werden in Base64.m einige Fehler angezeigt. Finden Sie die Zeilen, die so ähnlich sind

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

was Sie brauchen, ist das Löschen der Autorelease-Sektion. Das Endergebnis sollte so aussehen:

return [[self alloc] initWithBase64String:base64String];

Importieren Sie nun in Ihrem allgemeinen Projekt "Base64.h" und den folgenden Code

#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;
}

Mit

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

sie werden so etwas bekommen:

ghVEjPvxwLN1lBi0Jh46VpIchOc=

38
Zsivics Sanel

Dies ist die Komplettlösung, die ohne zusätzliche Bibliotheken oder Hacks auskommt:

+(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;
}

Sie müssen keine base64-Bibliothek eines Drittanbieters einbinden, da diese bereits codiert ist.

22
codeplasma

Dies funktioniert ohne die Verwendung von benutzerdefinierten Protokollen mit Code von 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

Verwendung:

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

So geht's, ohne dass externe Dateien einen Hex-String zurückgeben:

-(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;
}

Es wurde in xCode 5 mit iOS 7 getestet und funktioniert einwandfrei!

2
Neco

Ich verbringe einen ganzen Tag damit, den generierten Hash (Bytes) in lesbare Daten umzuwandeln. Ich habe die Base64-codierte Lösung aus der obigen Antwort verwendet und es hat bei mir überhaupt nicht funktioniert (nebenbei, du brauchst eine externe .h, um die Base64-Codierung verwenden zu können, die ich hatte).

Also, was ich getan habe, war dies (was perfekt ohne eine externe .h funktioniert):

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

// Now convert to NSData structure to make it usable again
NSData *out = [NSData dataWithBytes:cHMAC length:CC_SHA256_DIGEST_LENGTH];

// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
// hash is now a string with just the 40char hash value in it
NSLog(@"%@",hash);
2
bruno

Warum erstellen Sie aus Interesse (unsigned char cHMAC), konvertieren sie dann in (NSData) und konvertieren sie dann in (NSMutableString) und konvertieren sie schließlich in (HexString)?

Sie können dies schneller tun, indem Sie den Mittelsmann ausschalten (dh ohne NSData und NSMutableString insgesamt, schneller und mit besserer Leistung) und auch (unsigned char) in (uint8_t []) ändern, schließlich sind sie ohnehin alle Hex-Arrays! unten:

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

uint8_t cHMAC[CC_SHA1_DIGEST_LENGTH];

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

NSString *Hash1 = @"";
for (int i=0; i< CC_SHA1_DIGEST_LENGTH; i++)
{
    Hash1 = [Hash1 stringByAppendingString:[NSString stringWithFormat:@"%02X", cHMAC[i]]];
}
return Hash1;
}

Ich hoffe das hilft,

Grüße

Heider Sati

1
Heider Sati

Hast du Jens Alfkes neue MyCrypto Kurse gesehen?

Er hat einige Beispielcode auf seinem Blog .

0
Ford