私は、2 台の iPhone で公開鍵 (どちらもデバイス上で生成された鍵) を交換しようとして頭を回しています。キーは正常に生成され、データの暗号化などに使用できることをテストしました。今の目標は、XMPP メッセージを使用してキーを交換することです。したがって、キーを抽出し、それらを base64 エンコードして交換します。2 つのキーが交換され、それらを受け取ったら、次の関数を使用してキーチェーンに保存しようとします。
- (BOOL)storePublicKeyForContact:(WIMContactDetails *)contact publicKey:(NSString *)publicKey {
OSStatus sanityCheck = noErr;
NSString *contactTagString = contact.buddyFirstName;
contactTagString = [contactTagString stringByAppendingString:contact.buddyFacebookID];
NSLog(@"This is my public key identifier %@", contactTagString);
NSData *contactPublicTag = [NSData dataWithBytes:[contactTagString UTF8String] length:[contact.buddyPublicKeyIdentifier length]];
NSData *publicKeyBits = [NSData dataFromBase64String:publicKey];
//First deleting any existing keys
NSMutableDictionary *thePublicKey = [[NSMutableDictionary alloc] init];
[thePublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[thePublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[thePublicKey setObject:contactPublicTag forKey:(__bridge id)kSecAttrApplicationTag];
SecItemDelete((CFDictionaryRef)CFBridgingRetain(thePublicKey));
//adding a persistent version of the contact's publickey
[thePublicKey setObject:publicKeyBits forKey:(__bridge id)kSecValueData];
[thePublicKey setObject:(__bridge id)kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];
[thePublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrCanEncrypt];
[thePublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
CFTypeRef persistKey = nil;
sanityCheck = SecItemAdd((CFDictionaryRef) CFBridgingRetain(thePublicKey), (CFTypeRef *)&persistKey);
if (persistKey == nil || ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem))) {
NSLog(@"Error storing key for contact %@", contact.buddyFacebookFullName);
NSLog(@"Error Code is %ld", sanityCheck);
return (FALSE);
}
//Now to get the keyReference
SecKeyRef keyRef = nil;
[thePublicKey removeObjectForKey:(__bridge id)kSecValueData];
[thePublicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
[thePublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
[thePublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
sanityCheck = SecItemCopyMatching((CFDictionaryRef)CFBridgingRetain(thePublicKey), (CFTypeRef *)&keyRef);
if (keyRef == nil) {
NSLog(@"Stored key for contact %@", contact.buddyFacebookFullName);
NSLog(@"Error: Could not retrieve stored key!");
}
[contact setBuddyPublicKeyRef:keyRef];
if ([contact getBuddyPublicKeyRef] != nil) {
NSLog(@"Stored key for contact %@ successfully!!!", contact.buddyFacebookFullName);
}
return(TRUE);
}
PersistentRef を使用してキーを追加する時点まで、PersistRef は nil ではありません。SecItemCopyMatching を使用して SecKeyRef を取得するようにクエリを変更すると、結果は nil になります。最初は、それは間違った形式の問題だと思っていましたが、keyBits を抽出し (Apple ドキュメントの Security Excersice の関数を使用)、唯一の変更は NSData+base64 を使用することであるため、どうしてそうなるのでしょうか? .h ライブラリを使用して、交換のためにそれらをエンコードし、追加を試みる前にデコードします。
詳細については、キーを抽出するために使用する方法を参照してください
- (NSString *)getMyPublicKey {
OSStatus sanityCheck = noErr;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
// Set the public key query dictionary.
[queryPublicKey setObject:(id)CFBridgingRelease(kSecClassKey) forKey:(id)CFBridgingRelease(kSecClass)];
[queryPublicKey setObject:publicTag forKey:(id)CFBridgingRelease(kSecAttrApplicationTag)];
[queryPublicKey setObject:(id)CFBridgingRelease(kSecAttrKeyTypeRSA) forKey:(id)CFBridgingRelease(kSecAttrKeyType)];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)CFBridgingRelease(kSecReturnData)];
CFDataRef publicKeyBitsCF;
// Get the key bits.
sanityCheck = SecItemCopyMatching((CFDictionaryRef)CFBridgingRetain(queryPublicKey), (CFTypeRef *)&publicKeyBitsCF);
NSData *publicKeyBits = (__bridge_transfer NSData *)publicKeyBitsCF;
if (sanityCheck != noErr)
{
publicKeyBits = nil;
}
size_t keySize = SecKeyGetBlockSize([self getMyPublicKeyRef]);
NSData *data = [NSData dataWithBytes:(__bridge const void *)(publicKeyBits) length:keySize];
NSString *publicKey = [data base64EncodedString];
NSLog(@"%@",publicKey);
return publicKey;
}
ここで何が欠けているのか、誰でも推測できます。それはばかげていると確信していますが、セキュリティフレームワークに慣れていないので、わかりません。
よろしくお願いします:)