How can I compute a SHA-2 (ideally SHA 256 or SHA 512) hash in iOS?
Asked Answered
K

6

59

The Security services API doesn't appear to allow me to compute a hash directly. There are plenty of public domain and liberally licensed versions available, but I'd rather use a system library implementation if possible.

The data is accessible via NSData, or plain pointers.

The cryptographic strength of the hash is important to me. SHA-256 is the minimum acceptable hash size.

Kenzi answered 3/6, 2011 at 14:2 Comment(0)
B
81

This is what I'm using for SHA1:

#import <CommonCrypto/CommonDigest.h>

+ (NSData *)sha1:(NSData *)data {
    unsigned char hash[CC_SHA1_DIGEST_LENGTH];
    if ( CC_SHA1([data bytes], [data length], hash) ) {
        NSData *sha1 = [NSData dataWithBytes:hash length:CC_SHA1_DIGEST_LENGTH];        
        return sha1;
    }
return nil;
}

Replace CC_SHA1 with CC_SHA256 (or whichever you need), as well as CC_SHA1_DIGEST_LENGTH with CC_SHA256_DIGEST_LENGTH.

Ballou answered 3/6, 2011 at 14:28 Comment(4)
This didn't work.. converting the returned data to an NSString returned nil for me. The post below "hashed_string" worked if I passed in the data.Lawabiding
@Lawabiding - The question doesn't say anything about returning the SHA value as a hexadecimal string. Converting NSData to NSString can be a separate question on its own.Ballou
@alex-i, you are right, the NSData comes back, however the conversion to string I was mentioning does not work - you have to use the method that EgeAkpinar proposed below. I'm still curious what and how that works, however like you said that isn't the purpose of this post.Lawabiding
Swift version for this?Sedge
V
35

Here's a pretty similar one based on NSString

+ (NSString *)hashed_string:(NSString *)input
{
    const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:input.length];
    uint8_t digest[CC_SHA256_DIGEST_LENGTH];

    // This is an iOS5-specific method.
    // It takes in the data, how much data, and then output format, which in this case is an int array.
    CC_SHA256(data.bytes, data.length, digest);

    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];

    // Parse through the CC_SHA256 results (stored inside of digest[]).
    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [output appendFormat:@"%02x", digest[i]];
    }

    return output;
}

(Credits go to http://www.raywenderlich.com/6475/basic-security-in-ios-5-tutorial-part-1)

Veridical answered 2/11, 2012 at 16:15 Comment(2)
for iOS 7+ you to cast the data.length: CC_SHA256(data.bytes, (int)data.length, digest);Neomaneomah
data should be [NSData dataWithBytes:cstr length:strlen(cstr)]; It'd be better to use [input dataUsingEncoding:NSUTF8StringEncoding];Deserved
R
3

This is what worked for me

func sha256(securityString : String) -> String {
    let data = securityString.dataUsingEncoding(NSUTF8StringEncoding)!
    var hash = [UInt8](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
    CC_SHA256(data.bytes, CC_LONG(data.length), &hash)
    let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))
    for byte in hash {
        output.appendFormat("%02x", byte)
    }
    return output as String
}
Rooker answered 18/3, 2016 at 22:6 Comment(0)
G
0

Below link i used for creating document hash value and Its very simple and easy to calculate hash value specially for large files.

Link : http://www.joel.lopes-da-silva.com/2010/09/07/compute-md5-or-sha-hash-of-large-file-efficiently-on-ios-and-mac-os-x/comment-page-1/#comment-18533

Gypsum answered 12/12, 2016 at 7:33 Comment(1)
External links may disappear over time. Please include a self-contained piece of code in your answer.Indigestible
Y
0
+ (NSData *)sha256DataFromData:(NSData *)data {
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256([data bytes], (int)[data length], result);
    return [NSData dataWithBytes:result length:CC_SHA256_DIGEST_LENGTH];
}
Yolande answered 24/5, 2017 at 16:55 Comment(0)
F
0

I cleaned up https://mcmap.net/q/182459/-how-can-i-compute-a-sha-2-ideally-sha-256-or-sha-512-hash-in-ios a bit and structured it as an NSString extension

@interface NSString (SHA2HEX)

/*
 Get the SHA2 (256 bit) digest as a hex string.
 */
@property (nonatomic, readonly) NSString* sha2hex;
@end

@implementation NSString (SHA2HEX)

- (NSString*)sha2hex
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];

    if (data.length > UINT32_MAX)
        return nil;

    uint8_t digest[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(data.bytes, (CC_LONG)data.length, digest);

    const int hexlen = CC_SHA256_DIGEST_LENGTH * 2;
    NSMutableString *hexstr = [NSMutableString stringWithCapacity:hexlen];

    for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [hexstr appendFormat:@"%02x", digest[i]];
    }

    return hexstr;
}

@end
Flagpole answered 30/3, 2018 at 3:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.