Reputation: 2777
I'm trying to translate some hashcode that is written with .NET
into Objective-c
Syntax
SHA1 sha1 = new SHA1CryptoServiceProvider();
string hashedword = Convert.ToBase64String(sha1.ComputeHash(Encoding.ASCII.GetBytes(saltkey)))
This is what I have so far
NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *unicodePassword = [[NSString alloc] initWithData:data encoding:NSUnicodeStringEncoding];
data = [unicodePassword dataUsingEncoding:NSUnicodeStringEncoding];
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([data bytes], [data length], hash);
NSData *result = [NSData dataWithBytes:hash length:CC_SHA1_DIGEST_LENGTH];
At the end I want an hashed NSString
.
Can somebody help me with this ?
Upvotes: 0
Views: 428
Reputation: 539745
The NSUnicodeStringEncoding
conversions look suspicious in your code and seem
to be unnecessary. You have to use the same encoding as your .NET code.
I cannot test this with .NET, but
according to the documentation, Encoding.ASCII
uses the
replacement character ?
for all non-ASCII characters.
There is no equivalent NSStringEncoding
, but the same result
can be achieved with CoreFoundation methods:
NSString *password = ... // your password
CFIndex asciiLength;
// Determine length of converted data:
CFStringGetBytes((__bridge CFStringRef)(password), CFRangeMake(0, [password length]),
kCFStringEncodingASCII, '?', false, NULL, 0, &asciiLength);
// Allocate buffer:
uint8_t *asciiBuffer = malloc(asciiLength);
// Do the conversion:
CFStringGetBytes((__bridge CFStringRef)(password), CFRangeMake(0, [password length]),
kCFStringEncodingASCII, '?', false, asciiBuffer, asciiLength, NULL);
Now you can compute the SHA1 hash:
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(asciiBuffer, asciiLength, hash);
free(asciiBuffer);
NSData *result = [NSData dataWithBytes:hash length:CC_SHA1_DIGEST_LENGTH];
And finally the Base64-encoded string from the hash. Starting with iOS 7, there is a built-in method:
NSString *base64 = [result base64EncodedStringWithOptions:0];
A better option would be to use the UTF-8 encoding instead of ASCII encoding (for both .NET and Objective-C). In that case the code would simplify to
NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding];
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([data bytes], [data length], hash);
NSData *result = [NSData dataWithBytes:hash length:CC_SHA1_DIGEST_LENGTH];
NSString *base64 = [result base64EncodedStringWithOptions:0];
If the password contains only ASCII characters, both methods give the same result.
Upvotes: 1
Reputation: 437542
If you need that final base-64 string, you can use this code, which either calls the new iOS 7 base64EncodedStringWithOptions
or calls the now deprecated (and previously private) base64Encoding
method in earlier versions:
NSString *string;
if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
string = [result base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
} else {
string = [result base64Encoding]; // pre iOS7
}
Upvotes: 0