问题
For a new project I need to hash a NSString with SHA256. I have used the following code:
unsigned char hashedChars[32];
NSString *inputString;
inputString = [NSString stringWithFormat:@"hello"];
NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256(inputData.bytes, inputData.length, hashedChars);
I found this piece of code on stackoverflow. I do not really get all the things this code do here are some questions about the code:
1.The CC_SHA256 makes a hash but this hash will be stored in inputData again? What I mean can I do something like this:
NSString *string=CC_SHA256(..) //of course you can't put it directly in a NSString, but you get the point
2.In the end the hash has to be a hexadecimal string, but what is the type that CC_SHA256 outputs (UTF-8??)?
3.The first parameter of CC_SHA256 why do I have to put bytes at the end and is "inputData" enough?
4.What is the need of the length of the string (second parameter)?
5.And the last parameter does not make any sense to me, can somebody please explain and why the hashedChars has to be 32?
回答1:
The argument list for CC_SHA256 is:
extern unsigned char *CC_SHA256(const void *data, CC_LONG len, unsigned char *md);
From the man
page: https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CC_SHA256.3cc.html
Parameters explained:
*data
is the input string, what you want to be hashed. It's a C string-type. A way to get this is to call 'inputData.bytes', withinputData
aNSData
object.len
is the length of the input string. As you'll realize if you'll start working with C strings, it's pretty normal for functions working with strings to ask for the length. That's because in C strings are just a sequence of bytes, and while text strings are generally terminated by a null byte, binary strings can have any length. It's also for safety ("buffer overflows").*md
is the output. Again, this is returned as a C string, of fixed length 32 bytes for SHA256 (that's why you don't see anoutputLength
parameter).- The output is "not relevant", but can be used to check if the function ran properly:
if(CC_SHA256(...)) { all ok; }
The result string is stored into *md
, and it's a binary C string, 32 bytes long. It's 32 bytes long because that's the length of SHA256 digests; for example, 16 bytes for MD5, 20 bytes for SHA1, etc. It's just how the algorithm works!
The output is just a binary string. If you want to make it into hex format you need to store it into a NSData object, and then get a hex representation of it:
NSData *resultData = [NSData dataWithBytes:hashedChars length:32];
To get the hex representation then look at this SO answer: https://stackoverflow.com/a/25378464/192024
回答2:
If anyone trying to find a similar function for Android, the below snippet produces the same output as CC_SHA256
public static String calculateSH256(String secret){
final MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
byte[] bytes = secret.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
String sig = bytesToHex(digest.digest());
return sig;
}
catch (NoSuchAlgorithmException | UnsupportedEncodingException e){
throw new RuntimeException("Cannot calculate signature");
}
}
final protected static char[] hexArray = "0123456789abcdef".toCharArray();
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
来源:https://stackoverflow.com/questions/25044053/some-info-about-cc-sha256-objective-c