Error -9809 is
errSSLCrypto
, a general error that’s returned when the Security framework gets an error from the underlying crypto.
If you haven’t already looked at the CryptoCompatibility sample code, I suggest you do so. It shows how to implement various crypto algorithms on Apple platforms such that the results match other common crypto toolkits.
Unfortunately that version of CryptoCompatibility does not support OAEP. I have new version in the pipeline that does, but it’s not yet on the developer web site. In the meantime, I’ve pasted in some code below that shows the guts of the
QCCRSASmallCryptor
operation when using the legacy iOS crypto API (
SecKeyDecrypt
and friends). In OAEP mode this operation produces results that are compatible with macOS’s built-in
openssl
tool when you run it like this:
$ openssl rsautl -encrypt -oaep -pubin -inkey /path/to/public/key.pem -in /path/to/plaintext.dat
$ openssl rsautl -decrypt -oaep -inkey /path/to/private/key.pem -in /path/to/cyphertext.dat
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
- (void)runUsingRaw {
OSStatus err;
SecPadding padding;
NSMutableData * resultData;
size_t resultDataLength;
// Map our padding constant appropriately.
switch (self.padding) {
default:
assert(NO);
// fall through
case QCCRSASmallCryptorCompatPaddingPKCS1: {
padding = kSecPaddingPKCS1;
} break;
case QCCRSASmallCryptorCompatPaddingOẠEP: {
padding = kSecPaddingOẠEP;
} break;
}
// Do the crypto.
resultData = [[NSMutableData alloc] initWithLength:SecKeyGetBlockSize(self.key)];
resultDataLength = resultData.length;
switch (self.op) {
default:
assert(NO);
// fall through
case QCCRSASmallCryptorCompatOperationEncrypt: {
err = SecKeyEncrypt(
self.key,
padding,
self.smallInputData.bytes, self.smallInputData.length,
resultData.mutableBytes, &resultDataLength
);
} break;
case QCCRSASmallCryptorCompatOperationDecrypt: {
err = SecKeyDecrypt(
self.key,
padding,
self.smallInputData.bytes, self.smallInputData.length,
resultData.mutableBytes, &resultDataLength
);
} break;
}
// Set up the result.
if (err == errSecSuccess) {
// Set the output length to the value returned by the crypto. This is necessary because,
// in the decrypt case, the padding means we have allocated more space that we need.
resultData.length = resultDataLength;
self.smallOutputData = resultData;
} else {
self.error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil];
}
}