由于openssl在osx 10.7+中已弃用,我想从openssl切换到内部osx keychain和crypto函数。
但现在我被困在非对称加密/解密上。
如何使用非对称(RSA)密钥对随机生成的对称密钥进行加密/解密。使用openssl非常容易。
在apple dev docs中,他们说CommonCrypto支持非对称加密,但在检查标题时,我只能看到对对称内容的支持。
任何提示?
答案 0 :(得分:3)
查看加密消息语法服务,看看它是否可以满足您的需求。
另外,你正在误读OpenSSL的事情。不推荐使用随操作系统提供的OpenSSL库。这并不意味着你不能继续使用OpenSSL。 OpenSSL是开源的,没有什么能阻止你下载它并在你的应用程序中自由使用它。
Apple的弃用只是意味着如果您使用OpenSSL,则需要包含OpenSSL库的自己的副本,以便您负责保持您的OpenSSL库 - 到目前为止,并修复任何破损。 : - )
如果没有,iOS X非对称加密和解密功能(SecKeyEncrypt和SecKeyDecrypt)确实存在于OS X中,并且iOS标头甚至表明它们在OS X中可用。我不确定它们为什么不在OS X SDK。我提交了一个错误,它被标记为重复。
Apple可能无法在未打破模拟器的情况下删除这些功能,但是如果您提交到应用程序商店并且他们让您对使用它们感到悲伤,那么这里是SecKeyEncrypt构建的大致兼容的替代品使用安全转换API:
// Workaround for SecKeyEncrypt not really being public API in OS X
OSStatus OSXSecKeyEncrypt ( SecKeyRef key, SecPadding padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, size_t *cipherTextLen )
{
CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(
kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
CFErrorRef error = NULL;
SecTransformRef encrypt = SecEncryptTransformCreate(key, &error);
if (error) {
AFNSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
SecTransformSetAttribute(
encrypt,
kSecPaddingKey,
NULL, // kSecPaddingPKCS1Key (rdar://13661366 : NULL means kSecPaddingPKCS1Key and
// kSecPaddingPKCS1Key fails horribly)
&error);
CFDataRef sourceData = CFDataCreate(kCFAllocatorDefault, plainText, plainTextLen);
SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName,
sourceData, &error);
CFDataRef encryptedData = SecTransformExecute(encrypt, &error);
if (error) {
AFNSLog(@"Encryption failed: %@\n", (__bridge NSError *)error);
return (OSStatus)[(__bridge NSError *)error code];
}
if ((unsigned long)CFDataGetLength(encryptedData) > *cipherTextLen) {
return errSecBufferTooSmall;
}
*cipherTextLen = CFDataGetLength(encryptedData);
CFDataGetBytes(encryptedData, CFRangeMake(0, *cipherTextLen), cipherText);
return noErr;
}
您应该能够相当容易地调整代码以进行解密;我不需要它用于我的目的,所以我没有写那个功能。