【发布时间】:2020-01-01 14:17:45
【问题描述】:
我现在遇到了一些麻烦。 这些天我正在研究objc的RSA加密功能。但是当我完成该功能时,我发现我对“Keychain”存储密钥一无所知。我检查了 Apple 文档“将密钥存储在钥匙串中”和“获取现有密钥”和“生成新加密密钥”。并尝试使用 SecKeyCopyPublicKey( ), SecKeyCreateEncryptedData( , , ), SecItemCopyMatching( , ), SecKeyCreateRandomKey( , )…………我也尝试 google 获取一些有用的信息。
但还是有问题。这些是我这几天拼凑的完整代码:
AppDelegate.h
//
// AppDelegate.h
// MessagesServer
//
//
#import <Cocoa/Cocoa.h>
#import <Security/Security.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
AppDelegate.m
//
// AppDelegate.m
// MessagesServer
//
#import "AppDelegate.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSError * error = nil;
NSData * cipherText = [self encryptionDataUsingLocalRSAKey:[@"Hello! Nice to meet you!" dataUsingEncoding:NSUTF8StringEncoding] error:&error];
if (!cipherText){
NSLog(@"%@", error.description);
} else {
NSError * decryptErr = nil;
NSData * clearText = [self decryptionDataUsingLocalRSAKey:cipherText error:&decryptErr];
if (!clearText){
NSLog(@"%@", decryptErr.description);
} else {
NSLog(@"%@", [[NSString alloc] initWithData:clearText encoding:NSUTF8StringEncoding]);
}
}
}
- (NSData *)encryptionDataUsingLocalRSAKey:(NSData *)data error:(NSError **)encryptErr{
NSError * error = nil;
SecKeyRef privateKey = [self getRSAKeyInLocalWithError:&error];
if (!privateKey){
*encryptErr = error;
return nil;
}
SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey);
CFErrorRef encryptDataErr = nil;
NSData * cipherText = (NSData *)CFBridgingRelease(SecKeyCreateEncryptedData(publicKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA512, (__bridge CFDataRef)data, &encryptDataErr));
if (!cipherText){
*encryptErr = CFBridgingRelease(encryptDataErr);
return nil;
} else {
return cipherText;
}
}
- (NSData *)decryptionDataUsingLocalRSAKey:(NSData *)cipherData error:(NSError **)decryptErr{
NSError * error = nil;
SecKeyRef privateKey = [self getRSAKeyInLocalWithError:&error];
if (!privateKey){
*decryptErr = error;
return nil;
}
CFErrorRef decryptDataErr = nil;
NSData * clearText = (NSData *)CFBridgingRelease(SecKeyCreateDecryptedData(privateKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA512, (__bridge CFDataRef)cipherData, &decryptDataErr));
if (!clearText){
*decryptErr = CFBridgingRelease(decryptDataErr);
return nil;
} else {
return clearText;
}
}
- (SecKeyRef)getRSAKeyInLocalWithError:(NSError **)error{
NSDictionary * query = @{(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: [@"com.MessageSender.Server.Signing.Key" dataUsingEncoding:NSUTF8StringEncoding],
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
(id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate,
(id)kSecAttrIsPermanent: @YES,
(id)kSecReturnData: @YES,
(id)kSecAttrKeySizeInBits: @2048,
(id)kSecMatchLimit: (id)kSecMatchLimitOne,
};
SecKeyRef privateKey = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey);
if (status != errSecSuccess){
NSError * createError = nil;
BOOL createSuccess = [self createAnRSAKeyWithError:&createError];
if (!createSuccess){
*error = createError;
return nil;
} else {
privateKey = [self getRSAKeyInLocalWithError:nil];
}
}
return privateKey;
}
- (BOOL)createAnRSAKeyWithError:(NSError **)error{
NSDictionary * keyInfo = @{(id)kSecAttrType: (id)kSecAttrKeyTypeRSA,
(id)kSecAttrKeySizeInBits: @2048,
(id)kSecPublicKeyAttrs:
@{(id)kSecAttrLabel: @"MessageSender Server Encryption Key",
(id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: [@"com.MessageSender.Server.Encryption.Key" dataUsingEncoding:NSUTF8StringEncoding],},
(id)kSecPrivateKeyAttrs:
@{(id)kSecAttrLabel: @"MessageSender Server Signing Key",
(id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: [@"com.MessageSender.Server.Signing.Key" dataUsingEncoding:NSUTF8StringEncoding],},};
CFErrorRef createKeyError = nil;
SecKeyRef privateKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyInfo, &createKeyError);
if (!privateKey){
NSError * createKeyErr = CFBridgingRelease(createKeyError);
*error = createKeyErr;
return NO;
} else {
return YES;
}
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
很遗憾,这里运行时系统会报错,我google了半天也没有得到答案……
如果有任何帮助,我将不胜感激。谢谢!
【问题讨论】:
-
你能看到我发布的图片吗?
标签: objective-c key rsa keychain