63

Objective C で HMAC-SHA1 を生成する必要がありますが、機能するものが見つかりませんでした。CCHMAC を使用して CommonCrypto を試しましたが、うまくいきませんでした。hmac を生成し、HOTP 番号を生成する必要があります。

Objective C または C のコード例はありますか?

4

8 に答える 8

74

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 ライブラリについては知りませんが、私の記憶が正しければ、アルゴリズムは非常に単純でした。

于 2009-04-16T14:59:46.837 に答える
38

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=

 

于 2012-08-28T11:04:01.020 に答える
9

これは、 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

ハッシュSHA256.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;       
}
于 2011-11-27T19:12:52.017 に答える
3

これは、16 進文字列を返す外部ファイルなしで行う方法です。

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

iOS 7 の xCode 5 でテストされ、正常に動作します。

于 2013-10-10T17:40:14.580 に答える
1

興味深いことに、(unsigned char cHMAC) を作成してから (NSData) に変換してから (NSMutableString) に変換し、最後に (HexString) に変換するのはなぜですか?

仲介者をカットすることでこれをより迅速に行うことができます (つまり、NSData と NSMutableString をまったく使用せずに、より高速でパフォーマンスを向上させます)。また、(unsigned char) を (uint8_t []) に変更します。下:

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

これが役に立てば幸いです。

よろしく

ハイダー・サティ

于 2013-11-08T04:39:30.680 に答える
1

生成されたハッシュ (バイト) を読み取り可能なデータに変換しようとして、丸一日を費やしました。上記の回答のbase64でエンコードされたソリューションを使用しましたが、まったく機能しませんでした(必要なのは、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);
于 2011-10-12T09:40:33.520 に答える
0

Jens Alfke の新しいMyCryptoクラスを見たことがありますか?

彼のブログにいくつかのサンプル コードがあります。

于 2009-04-16T15:23:20.093 に答える