2013-05-25 3 views
14

मेरे पास दो कुंजी, सार्वजनिक और निजी हैं, जो दोनों SecKeyRef-Variables में संग्रहीत हैं। सादगी के लिए, आइए जनता के साथ शुरू करें। मैं जो करना चाहता हूं उसे एनएसडीटा ऑब्जेक्ट में निर्यात करना है। कि के लिए, वहाँ है एक लगभग प्रसिद्ध कोड स्निपेट एप्पल, जो यहाँ है द्वारा प्रदान:आईएसओ SecKeyRef NSData

- (NSData *)getPublicKeyBits { 
    OSStatus sanityCheck = noErr; 
    NSData * publicKeyBits = nil; 

    NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init]; 

    // Set the public key query dictionary. 
    [queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass]; 
    [queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag]; 
    [queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType]; 
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData]; 

    // Get the key bits. 
    sanityCheck = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits); 

    if (sanityCheck != noErr) 
    { 
     publicKeyBits = nil; 
    } 

    [queryPublicKey release]; 

    return publicKeyBits; 
} 

मैं Xcode 4.6.2, तथापि है, और कोड गलत प्रतीत होता है ("__bridge" आईडी के लिए प्रत्येक रूपांतरण से पहले जोड़ा जाता है)। नए संस्करण इस तरह दिखता है:

- (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey { 
    OSStatus sanityCheck = noErr; 
    NSData * publicKeyBits = nil; 

    NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init]; 

    // Set the public key query dictionary. 
    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag]; 
    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnData]; 

    // Get the key bits. 
    sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits); 

    if (sanityCheck != noErr) 
    { 
     publicKeyBits = nil; 
    } 

    return publicKeyBits; 
} 

अभी भी दो त्रुटियों, हालांकि इस प्रकार हैं: करने के लिए 'publicTag'

  • एक ऑब्जेक्टिव-सी सूचक को एक अप्रत्यक्ष सूचक की कास्ट अघोषित पहचानकर्ता के

    • उपयोग 'CFTypeRef ' (उर्फ 'स्थिरांक शून्य *') एआरसी

    अब साथ स्वीकृत नहीं है तो मुझे आशा है कि आपकी मदद की, पहला मुद्दा w के बाद बीमार अब कोई समस्या नहीं है, क्योंकि मैं एक प्रश्न बनाना नहीं चाहता हूं या कुंजीपटल से कुंजी निकालने के लिए क्या नहीं करना चाहता। मेरे पास यह एक चर में है और मैं इसे वहां से निकालना चाहता हूं। परिवर्तनीय का नाम givenPublicKey है, और यही वह कुंजी है जिसे मैं NSData में परिवर्तित करना चाहता हूं।

    तो, मैं यह करने और इस एआरसी-मुद्दे को हल करने के बारे में कैसे जाउंगा?

    फ़ॉलो-अप: मैं NSData करने के लिए एक निजी कुंजी निर्यात कर सकते हैं कैसे, के बाद से मैं कई बार समारोह मैं केवल के साथ काम करने की कोशिश कर रहा हूँ सार्वजनिक कुंजी के लिए काम करता है कि पढ़ा है।

  • +0

    क्या आप ऐप्पल के दस्तावेज़/साइट पर कोड स्निपेट का संदर्भ दे सकते हैं? – MCKapur

    +0

    निश्चित रूप से, यह है: http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html#//apple_ref/doc/uid/DTS40008019-Classes_SecKeyWrapper_m-DontLinkElementID_17 – arik

    उत्तर

    11
    • अघोषित पहचानकर्ता 'publicTag'

    publicTag के उपयोग सिर्फ कुछ अद्वितीय कीचेन आइटम को जोड़ा गया पहचानकर्ता है। CryptoExercise नमूना परियोजना में यह 'के रूप में CFTypeRef' (उर्फ 'स्थिरांक शून्य *') के लिए एक ऑब्जेक्टिव-सी सूचक को एक अप्रत्यक्ष सूचक की

    #define kPublicKeyTag "com.apple.sample.publickey" 
    static const uint8_t publicKeyIdentifier[] = kPublicKeyTag; 
    NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 
    
    • कास्ट परिभाषित किया गया है एआरसी के साथ की अनुमति नहीं है

    यह एक अस्थायी CFTypeRef चर का उपयोग करके हल किया जा सकता:

    CFTypeRef result; 
    sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, &result); 
    if (sanityCheck == errSecSuccess) { 
        publicKeyBits = CFBridgingRelease(result); 
    } 
    
    • मैं निर्माण करने के लिए नहीं करना चाहते हैं कुंजीपटल से कुंजी निकालने के लिए एक क्वेरी या क्या नहीं। मेरे पास एक चर में है और मैं इसे वहां से निकालना चाहता हूं ...

    जहां तक ​​मुझे पता है, आपको SecKeyRef को अस्थायी रूप से कीचेन में स्टोर करना होगा। SecItemAdd में जोड़ा गया आइटम डेटा के रूप में वापस करने का विकल्प है। प्रलेखन से:

    प्रकार CFDataRef की एक वस्तु के रूप में जोड़ा आइटम के डेटा प्राप्त करने के लिए, वापसी प्रकार कुंजी kSecReturnData kCFBooleanTrue के एक मूल्य के साथ निर्दिष्ट करें।

    एक साथ यह सब लाना है, तो निम्न कोड आप क्या चाहते हैं करना चाहिए:

    - (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey { 
    
        static const uint8_t publicKeyIdentifier[] = "com.your.company.publickey"; 
        NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 
    
        OSStatus sanityCheck = noErr; 
        NSData * publicKeyBits = nil; 
    
        NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init]; 
        [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
        [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag]; 
        [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
    
        // Temporarily add key to the Keychain, return as data: 
        NSMutableDictionary * attributes = [queryPublicKey mutableCopy]; 
        [attributes setObject:(__bridge id)givenKey forKey:(__bridge id)kSecValueRef]; 
        [attributes setObject:@YES forKey:(__bridge id)kSecReturnData]; 
        CFTypeRef result; 
        sanityCheck = SecItemAdd((__bridge CFDictionaryRef) attributes, &result); 
        if (sanityCheck == errSecSuccess) { 
         publicKeyBits = CFBridgingRelease(result); 
    
         // Remove from Keychain again: 
         (void)SecItemDelete((__bridge CFDictionaryRef) queryPublicKey); 
        } 
    
        return publicKeyBits; 
    } 
    

    मुझे आशा है कि यह काम करता है, मैं इस समय यह परीक्षण नहीं कर सकते।

    • फ़ॉलो-अप: मैं NSData करने के लिए एक निजी कुंजी निर्यात कर सकते हैं कैसे, के बाद से मैं कई बार हुआ है कि समारोह मैं केवल के साथ काम करने की कोशिश कर रहा हूँ सार्वजनिक कुंजी के लिए काम करता है पढ़ा है।

    मुझे नहीं पता।

    +0

    धन्यवाद, यह काम करता है ! – arik

    +0

    क्या हम इसे मैक के लिए उपयोग कर सकते हैं? रिटर्न त्रुटि - अमान्य कुंजी जब – Adwait

    +1

    का उपयोग किया जाता है तो मुझे मुख्य डेटा के लिए एक अजीब आकार मिलता है। मेरे मामले में मैंने 2048 बिट कुंजी (256 बाइट्स) के साथ एक पहचान आयात की, हालांकि इस समारोह से लौटाई गई एनएसडीटा का आकार 270 बाइट है। – liamo