2009-03-16 2 views
42

Можно создать дубликат:
MD5 algorithm in Objective CИспользование хеша MD5 на веревке в какао?

Мне нужно хэш строки, используя метод MD5 в какао. Любые фреймворки, которые используются, должны быть доступны на iphone. пожалуйста, предоставьте код, если это возможно.

+1

, если это возможно, не используйте md5 но и SHA-хеш. MD5 считается сломанным. –

+6

MD5 не «сломан», есть одна конкретная уязвимость, которая позволяет создать конфликт, когда у вас уже есть довольно много информации об хэшируемых данных. Это по-прежнему абсолютно правильный выбор для приложений, таких как проверка паролей (хотя использование соли всегда является хорошей идеей). –

+2

Использование MD5 для криптографических целей неразумно. Вот как можно реплицировать хеш MD5: http://www.mscs.dal.ca/~selinger/md5collision/ Эти инструменты занимают несколько часов в поле класса ПК. Вот, как подделать цифровой сертификат MD5: http://www.schneier.com/crypto-gram-0901.html Подробнее об атаках: http://www.schneier.com/blog/ архивы/2005/06/more_md5_collis.html –

ответ

36

Ну, во-первых, MD5 не является шифром. Поэтому, если вы ищете шифрование, вы ищете не то место.

Но если вы просто хотите, чтобы хеш-то с помощью MD5 на iPhone, это должно дать вам информацию, нужно:

#import <CommonCrypto/CommonDigest.h> 

NSString *md5(NSString *str) { 
    const char *cStr = [str UTF8String]; 
    unsigned char result[CC_MD5_DIGEST_LENGTH]; 
    CC_MD5(cStr, strlen(cStr), result); 
    return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", 
     result[0], result[1], 
     result[2], result[3], 
     result[4], result[5], 
     result[6], result[7], 
     result[8], result[9], 
     result[10], result[11], 
     result[12], result[13], 
     result[14], result[15] 
    ]; 
} 

//… 

NSString *digest = md5(@"test"); 
NSLog(@"MD5 TEST %@", digest); 

(От Calculate MD5 on iPhone)

+43

Правильно, но -1. Я использую stackoverflow, чтобы избежать других форумов. Пожалуйста, подумайте о том, чтобы отправлять фактический ответ, а не ссылку. – bentford

3

MD5 не шифрования, это cryptographic hash function. Это односторонняя функция, выход которой - 128-битное число. Тот факт, что это криптографический, означает, что это сложная проблема, которая, учитывая выход хэш-файла MD5, вычисляет строку, MD5 которой это значение. Таким образом, MD5 может использоваться для проверки целостности данных, но не для шифрования.

+1

Следует отметить, что MD5 был скомпрометирован, так что уже невозможно атаковать его. Это может быть неважно, в зависимости от того, для чего вы его используете, но это стоит иметь в виду. http://en.wikipedia.org/wiki/MD5#Vulnerability –

+8

Следует отметить, что исходный плакат не запрашивал шифрования ... –

+1

Сначала они сделали. – Joe

6

Я добавил следующее к моей категории "NSString + MyGoonk":

#include <openssl/md5.h> 

- (NSString *)md5 
{ 
    NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding]; 
    unsigned char *digest = MD5([data bytes], [data length], NULL); 
    return [NSString stringWithUTF8String: (char *)digest]; 
} 

Две вещи:

  1. это предполагает, что строка UTF8. Я уверен, что есть способ сделать его более общим, но я почти никогда не использую ничего другого.

  2. Вы должны установить ссылку -lcrypto в свой проект.

+0

Это устарело, начиная с OS X 10.7. – Pripyat

19

Это то, что я использую. Кредиты идут до Alistair McMillan.

#import <CommonCrypto/CommonDigest.h> 


+ (NSString *) md5:(NSString *)str { 
const char *cStr = [str UTF8String]; 
unsigned char result[16]; 
CC_MD5(cStr, strlen(cStr), result); 
return [NSString stringWithFormat: 
    @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", 
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7], 
    result[8], result[9], result[10], result[11], 
    result[12], result[13], result[14], result[15] 
    ]; 
} 

Примечание # 1: У меня не было связать с любыми библиотеками

Примечание # 2: Я не мог найти -lcrypto во внешнем списке рамочным на Iphone, и это работает без -lcrypto

6

Проведя слишком много времени, пытаясь понять это, я сделал всеобъемлющее сообщение с правильным кодом и как его использовать. Вы можете найти сообщение здесь в своем блоге. http://www.saobart.com/md5-has-in-objective-c/

+0

Спасибо. Очень полезно. – znq

+0

Спасибо человек. Я думаю, что это правильный ответ. – itsaboutcode

+0

Стоит отметить, что это решение идентично приведенному выше коду. – bentford

67

Заметил это в исходном коде Facebook. Выглядит довольно солидно, дайте ему шанс.

#import <CommonCrypto/CommonDigest.h> 

... 

+ (NSString*)md5HexDigest:(NSString*)input { 
    const char* str = [input UTF8String]; 
    unsigned char result[CC_MD5_DIGEST_LENGTH]; 
    CC_MD5(str, strlen(str), result); 

    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2]; 
    for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) { 
     [ret appendFormat:@"%02x",result[i]]; 
    } 
    return ret; 
} 
... 
+9

+1 это в основном эквивалентно моему фрагменту выше, но выглядит немного чище. – bentford

+3

@bentford: более чистые решения лучше. – FreeAsInBeer

+1

Чтобы отключить предупреждение в XCode cast 'strlen (str)' to '(CC_LONG) strlen (str)' – Jasper

10

Стоит отметить, что методы OpenSSL являются устаревшими на более поздних версиях OS X, и MD5 дайджест обычно в нижнем регистре. Лично я больше поклонник разворачиваемого стиля для эффективности, и я думаю, что использование категорий ObjC для этого лучше подходит.

Для MD5Digest.ч: #include

@interface NSString (MD5Digest) 
- (NSString*) md5Digest; 
@end 

@interface NSData (MD5Digest) 
- (NSString*) md5Digest; 
@end 

И MD5Digest.m:

#include <CommonCrypto/CommonDigest.h> 
#include "MD5Digest.h" 

static NSString* md5Digest(const void *data, CC_LONG length) 
{ 
    unsigned char digest[CC_MD5_DIGEST_LENGTH]; 
    unsigned char* d = CC_MD5(data, length, digest); 

    return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15], 
     nil]; 
} 

@implementation NSString (MD5Digest) 

- (NSString*) md5Digest 
{ 
    return md5Digest([self UTF8String], [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); 
} 

@end 

@implementation NSData (MD5Digest) 

- (NSString*) md5Digest 
{ 
    return md5Digest([self bytes], [self length]); 
} 

@end 
+0

Чтобы исправить предупреждения компилятора и потенциальную проблему с данными> 4 ГБ, я использовал: return md5Digest ([self bytes], (CC_LONG) MIN (UINT32_MAX, [self length])); – dbainbridge

Смежные вопросы