18

So I need to generate a Sha256 password in Objective-C, and can't figure out for the life of me how to do it! Is there something easy I'm just missing?

I've tried implementing the following method (which was written for iPhone, but I figured maybe it'd work cross-platform, as some Objective-C code does)

-(NSString*)sha256HashFor:(NSString*)input
{
    const char* str = [input UTF8String];
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(str, strlen(str), result);

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

But that just spat out errors about CC_SHA256_DIGEST_LENGTH being an undeclared identifier.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
garetmckinley
  • 1,122
  • 2
  • 11
  • 29

5 Answers5

24

You need to include the appropriate header file:

#include <CommonCrypto/CommonDigest.h>

According to the Cryptographic Services documentation this should be available on both iOS and OS X.

In OS X v10.5 and later and iOS 5.0 and later, Common Crypto provides low-level C support for encryption and decryption. Common Crypto is not as straightforward as Security Transforms, but provides a wider range of features, including additional hashing schemes, cipher modes, and so on.

James Holderness
  • 22,721
  • 2
  • 40
  • 52
11
#import <CommonCrypto/CommonDigest.h>

Objective-C: SHA256 is only two lines:

+ (NSData *)doSha256:(NSData *)dataIn {
    NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(dataIn.bytes, dataIn.length, macOut.mutableBytes);
    return macOut;
}

Swift 3

func sha256Hex(string: String) -> String? {
    guard let messageData = string.data(using:String.Encoding.utf8) else { return nil }
    var digestData = Data(count: Int(CC_SHA256_DIGEST_LENGTH))

    _ = digestData.withUnsafeMutableBytes {digestBytes in
        messageData.withUnsafeBytes {messageBytes in
            CC_SHA256(messageBytes, CC_LONG(messageData.count), digestBytes)
        }
    }

    return digestData.map { String(format: "%02hhx", $0) }.joined()
}

// Test

let sha256HexString = sha256Hex(string:"Hello")
print("sha256HexString: \(sha256HexString!)")

sha256HexString: "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969"

zaph
  • 111,848
  • 21
  • 189
  • 228
  • i am trying to convert it to nsstring in order to save it to database but its not working. Could you please tell me know to store the SHA256 key to database: NSString* newStr = [[NSString alloc] initWithData:sha256 encoding:NSUTF8StringEncoding]; – Vikas Bansal Oct 14 '15 at 06:13
  • 1
    It is not possible to convert arbitrary data into a string, not all 8-bit bytes map to character encodings. There are two common options: hexadecimal or Base64 representations.There may also be the option of putting the raw data into the database. – zaph Oct 14 '15 at 10:52
  • now, I am doing it like this.. Is this correct? NSString * str = [sha256Data base64EncodedStringWithOptions:0]; – Vikas Bansal Oct 14 '15 at 11:09
6

Objective-C method whose output matches output from random site online

-(NSString*)sha256HashForText:(NSString*)text {
    const char* utf8chars = [text UTF8String];
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(utf8chars, (CC_LONG)strlen(utf8chars), result);

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

Taken from this Gist.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
3

a modified version of @zaph answer in Objective-C with NSString as input and output:

-(NSString*)sha256HashFor:(NSString*)input
{
    NSData* data = [input dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData *sha256Data = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
    CC_SHA256([data bytes], (CC_LONG)[data length], [sha256Data mutableBytes]);
    return [sha256Data base64EncodedStringWithOptions:0];
}
Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76
1

Check out the NSHash cocoa pod. It has a bunch of different hashing methods including SHA256.

https://github.com/jerolimov/NSHash

Jeff Ames
  • 1,555
  • 11
  • 27