42

Possible Duplicate:
MD5 algorithm in Objective C

I need to hash a string using the MD5 technique in cocoa. Any frameworks that are used must be able to be accessed on the iphone. please provide code if possible.

Community
  • 1
  • 1
zpesk
  • 4,343
  • 7
  • 39
  • 61
  • 1
    if possible, don't use md5 but a sha-hash. MD5 is considered to be broken. – Georg Schölly Mar 16 '09 at 22:41
  • 6
    MD5 isn't "broken", there's one particular vulnerability that allows you to create a collision when you already have quite a bit of information about the data being hashed. It's still a perfectly valid choice for applications like verifying passwords (though using a salt is always a good idea). – Chad Birch Mar 16 '09 at 23:03
  • 2
    Use of MD5 for cryptographic purposes is unwise. Here's how to replicate an MD5 hash: http://www.mscs.dal.ca/~selinger/md5collision/ These tools take a few hours on a PC-class box. Here's how to forge an MD5 digital certificate: http://www.schneier.com/crypto-gram-0901.html Here's some more details on attacks: http://www.schneier.com/blog/archives/2005/06/more_md5_collis.html – Stephen Hoffman Aug 18 '09 at 18:05
  • 6
    I dont think mixing hashis with cocoa is very tasty. You'd have a hard time balancing it on the string too. – Jonny Jan 21 '11 at 11:14

7 Answers7

67

Noticed this in the Facebook Connect source code. Looks pretty solid, give it a shot.

#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;
}
...
Jackie Treehorn
  • 826
  • 1
  • 7
  • 5
36

Well, first off, MD5 isn't encryption. So if you're looking for encryption, you're looking in the wrong place.

But if you just want to hash something using MD5 on an iPhone, this should give you the information you need:

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

(From Calculate MD5 on iPhone)

mxcl
  • 26,392
  • 12
  • 99
  • 98
Chad Birch
  • 73,098
  • 23
  • 151
  • 149
  • 43
    Correct, but -1. I use stackoverflow to avoid other forum sites. Please consider posting an actual answer rather than a link. – bentford Jan 20 '10 at 00:37
19

This is what I use. Credits go to 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]
  ]; 
}

NOTE #1: I didn't have to link to any libraries

NOTE #2: I couldn't find -lcrypto in the external framework list on the iphone, and this works without -lcrypto

bentford
  • 33,038
  • 7
  • 61
  • 57
10

It's worth mentioning that the OpenSSL methods are deprecated on more recent versions of OS X, and the MD5 digest is conventionally lower case. Personally I'm more a fan of the unrolled style for efficiency, and I think using ObjC categories for this is a better fit.

For MD5Digest.h: #include

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

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

And 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
Tom M
  • 141
  • 2
  • 4
  • To fix the compiler warnings and potential issue with data > 4GB I used: return md5Digest([self bytes], (CC_LONG)MIN(UINT32_MAX, [self length])); – dbainbridge Nov 28 '13 at 21:05
6

I added the following to my "NSString+MyGoonk" category:

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

Two things:

  1. this assumes your string is UTF8. I'm sure there's a way to make it more generic, but I almost never use anything else.

  2. you have to link -lcrypto into your project.

MarcWan
  • 2,943
  • 3
  • 28
  • 41
6

After spending too much time trying to figure this out I made a comprehensive post with correct code and how to use it. You can find the post here on my blog. http://www.saobart.com/md5-has-in-objective-c/

Chris Beaven
  • 69
  • 1
  • 1
  • It's worth noting that this solution is identical to the code I posted above. – bentford Dec 30 '10 at 06:19
  • @bentford It's not identical; yours is more efficient. Code in the above blog uses %02X then converts to lowercase after... – JosephH Oct 20 '11 at 12:13
3

MD5 is not encryption, it is a cryptographic hash function. It's a one-way function whose output is a 128-bit number. The fact that it is cryptographic means that it is a computationally hard problem that, given an MD5 hash output, compute a string whose MD5 is that value. So, MD5 can be used for data integrity checks, but not for encryption.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • 1
    It should be noted that MD5 has been compromised so that it's no longer infeasible to attack it. That might not matter depending on what you're using it for, but it's worth keeping in mind. http://en.wikipedia.org/wiki/MD5#Vulnerability – James Williams Mar 16 '09 at 22:52
  • 8
    It should be noted that the original poster didn't ask for encryption… – Martin Marconcini Oct 06 '09 at 10:33