The best way to do this, at least in my experience, is to write a small Objective-C wrapper for the CommonCrypto functionality you need and then use that wrapper from your Swift code. Pasted in below is an example of this from a test project of mine.
There are other choices here:
However, I think the approach outline below represents a good balance between minimising your Objective-C code and avoiding extra complexity in the tools.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
In my bridging header:
#import "SecurityHelpers.h"
In my
SecurityHelpers.h
:
@import Foundation;
typedef NS_ENUM(NSInteger, SecDigestAlgorithm) {
SecDigestAlgorithmSHA1,
SecDigestAlgorithmSHA224,
SecDigestAlgorithmSHA256,
SecDigestAlgorithmSHA384,
SecDigestAlgorithmSHA512
};
/*! Returns a digest of the specified data.
* \param algorithm The digest algorithm to use.
* \param data The data to digest.
* \returns A digest of that data.
*/
extern NSData * SecCreateDigest(SecDigestAlgorithm algorithm, NSData * data);
In my
SecurityHelpers.m
:
#import "SecurityHelpers.h"
#include <CommonCrypto/CommonCrypto.h>
extern NSData * SecCreateDigest(SecDigestAlgorithm algorithm, NSData * data) {
NSUInteger size;
unsigned char *(*digester)(const void *data, CC_LONG len, unsigned char *md);
NSMutableData * digest;
switch (algorithm) {
case SecDigestAlgorithmSHA1: size = CC_SHA1_DIGEST_LENGTH; digester = CC_SHA1; break;
case SecDigestAlgorithmSHA224: size = CC_SHA224_DIGEST_LENGTH; digester = CC_SHA224; break;
case SecDigestAlgorithmSHA256: size = CC_SHA256_DIGEST_LENGTH; digester = CC_SHA256; break;
case SecDigestAlgorithmSHA384: size = CC_SHA384_DIGEST_LENGTH; digester = CC_SHA384; break;
case SecDigestAlgorithmSHA512: size = CC_SHA512_DIGEST_LENGTH; digester = CC_SHA512; break;
default:
abort();
}
digest = [[NSMutableData alloc] initWithLength:size];
digester(data.bytes, (CC_LONG) data.length, digest.mutableBytes);
return digest;
}
In my Swift code:
let content: Data = …
let messageDigest = SecCreateDigest(.SHA256, content)