I am trying to encrypt some NSData
using SecKeyEncrypt
function. The problem is, it returns an error -50
, which according to documentation is
errSecParam
One or more parameters passed to the function are not valid.
The problem is, I can't find anything wrong with my function. Code is as follows
- (NSData *)encryptWithPrivateKey:(NSData *)plainData
{
if (!privateKeyRef) {
RBLog(@"No private key");
return nil;
}
if (!plainData.length) {
RBLog(@"Plain data empty");
return nil;
}
size_t blockSize = SecKeyGetBlockSize(privateKeyRef); // 128
NSMutableData *encryptedData = [[NSMutableData alloc] initWithCapacity:blockSize]; // using capacity of 1024 changes nothing
size_t encryptedDataLen = blockSize;
OSStatus status = SecKeyEncrypt(privateKeyRef,
kSecPaddingPKCS1,
(const uint8_t *)plainData.bytes,
plainData.length,
(uint8_t *)encryptedData.bytes,
&encryptedDataLen);
if (status != errSecSuccess) {
RBLog(@"Could not encrypt, OS status %@", @(status));
}
return [NSData dataWithData:encryptedData];
}
The key is created using SecKeyGeneratePair
which returns errSecSuccess
. As you can see, I'm trying to encrypt the data with private key, not public one, so I have added
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrCanEncrypt];
to private key parameters upon generation, but that unfortunatelly didn't help.
What is the issue here?
I managed to find the solution.
What I actually wanted to do was to have the data signed (that's why I was using private key to encrypt instead of public one), but it turns out CommonCrypto
has a specific function just for that, so using
OSStatus status = SecKeyRawSign(privateKeyRef,
kPadding,
(const uint8_t *)plainText.bytes,
plainText.length,
(uint8_t *)encryptedData.bytes,
&encryptedDataLen);
solved the issue.