IT Share you

HMAC-SHA1 용 Objective-C 샘플 코드

shareyou 2020. 11. 26. 20:22
반응형

HMAC-SHA1 용 Objective-C 샘플 코드


Objective C에서 HMAC-SHA1을 생성해야합니다.하지만 작동하는 것을 찾지 못했습니다. CCHMAC를 사용하여 CommonCrypto로 시도했지만 작동하지 않았습니다. hmac을 생성하고 HOTP 번호를 생성해야합니다.

누군가 Objective C 또는 C에 예제 코드가 있습니까?


SHA-256을 사용하여 HMAC를 생성하는 방법은 다음과 같습니다.

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];

나는 HOTP 라이브러리를 알지 못하지만 올바르게 기억한다면 알고리즘은 매우 간단했습니다.


다음은 HMAC-SHA1 base64를 생성하는 방법 입니다.

프로젝트에 Base64.h 및 Base64.m을 추가해야합니다. 여기 에서 얻을 수 있습니다 .

ARC를 사용하는 경우 Base64.m에 일부 오류가 표시됩니다. 비슷한 줄 찾기

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

필요한 것은 autorelease 섹션을 삭제하는 것입니다. 최종 결과는 다음과 같아야합니다.

return [[self alloc] initWithBase64String:base64String];

이제 일반 프로젝트에서 "Base64.h"와 다음 코드를 가져옵니다.

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

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

다음과 비슷한 내용이 표시됩니다.

ghVEjPvxwLN1lBi0Jh46VpIchOc=

 


이것은 추가 라이브러리 나 해킹없이 작동하는 완전한 솔루션입니다.

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

이미 인코딩되어 있으므로 타사 base64 라이브러리를 포함 할 필요가 없습니다.


이것은 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

용법:

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

하루 종일 생성 된 해시 (바이트)를 읽을 수있는 데이터로 변환하려고합니다. 위의 답변에서 base64 인코딩 솔루션을 사용했지만 전혀 작동하지 않았습니다 (btw 필요하고 내가 가지고 있던 base64 인코딩을 사용할 수있는 외부 .h).

그래서 내가 한 것은 (외부 .h없이 완벽하게 작동하는) 다음과 같습니다.

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);

This is how yo do it without external files returning an hex string:

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

It was tested in xCode 5 with iOS 7 and works fine!


Out of interest, why do you create (unsigned char cHMAC) and then convert into (NSData) and then convert it into (NSMutableString) and then convert finally into (HexString)?

You could do this in a quicker way by cutting the middleman (i.e. without NSData and NSMutableString altogether, quicker and better performance), also changing (unsigned char) into (uint8_t []), after all they are all hex-arrays anyway!, below:

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

I hope this helps,

Regards

Heider Sati


Have you seen Jens Alfke's new MyCrypto classes?

He has some sample code on his blog.

참고URL : https://stackoverflow.com/questions/756492/objective-c-sample-code-for-hmac-sha1

반응형