You can solve this much easier with no external sources or components.
I found out how and wanted to share it so i may help others.
- You need to load the key file a SecKeyRef and safe the maxPlainLen as well
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:privateKeyResourceName ofType:@"p12"]; NSData *p12Data = [NSData dataWithContentsOfFile:resourcePath]; NSMutableDictionary * options = [[NSMutableDictionary alloc] init]; SecKeyRef privateKeyRef = NULL; //change to the actual password you used here [options setObject:@"_YOURPASSWORDHERE__" forKey:(__bridge id)kSecImportExportPassphrase]; CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data, (__bridge CFDictionaryRef)options, &items); if (securityError == noErr && CFArrayGetCount(items) > 0) { CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef); if (securityError != noErr) { privateKeyRef = NULL; } } CFRelease(items); privateKey = privateKeyRef; maxPlainLen = SecKeyGetBlockSize(privateKey) - 12;
- You can convert NSString with a category method to SHA1
- (NSData*)toSha1AsData { // PHP uses ASCII encoding, not UTF const char *s = [self cStringUsingEncoding:NSASCIIStringEncoding]; NSData *keyData = [NSData dataWithBytes:s length:strlen(s)]; // This is the destination uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0}; // This one function does an unkeyed SHA1 hash of your hash data CC_SHA1(keyData.bytes, keyData.length, digest); // Now convert to NSData structure to make it usable again NSData *out = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH] return out; }
- Now you can sign your SHA1 with this method
(NSData *)signSha1Data:(NSData *)data {
size_t plainLen = [data length];
if (plainLen > maxPlainLen)
{
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[data getBytes:plain
length:plainLen];
size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyRawSign(privateKey, kSecPaddingPKCS1SHA1,
plain, plainLen, cipher, &cipherLen);
NSData *result = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
It works very well and without any external libs. There is no need to compile some wierd openssl stuff.