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を追加する必要があります。 here から取得できます。
ARCを使用する場合、Base64.mでいくつかのエラーが表示されます。このような類似の行を見つけます
return [[[self alloc] initWithBase64String:base64String] 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;
}
これは、外部ファイルが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でテストされ、正常に動作します!
生成されたハッシュ(バイト)を読み取り可能なデータに変換しようとして、1日を過ごします。上記の答えからbase64エンコードされたソリューションを使用しましたが、それはまったく機能しませんでした(b.t.w.必要であり、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);
興味深いことに、なぜ(unsigned char cHMAC)を作成してから(NSData)に変換してから(NSMutableString)に変換してから、最後に(HexString)に変換するのですか?
NSDataとNSMutableStringをまったく使用せずに(つまり、より高速で優れたパフォーマンスを実現する)仲介者を切断することにより、これをより迅速に行うことができます。以下:
-(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;
}
これがお役に立てば幸いです、
よろしく
ハイダー・サティ
Jens Alfkeの新しい MyCrypto クラスを見ましたか?
彼にはいくつかの 彼のブログのサンプルコード があります。