11

I need to send my public key that has been generated by SecKeyGeneratePair as a SecKeyRef object. Now, to send this, i need this KeyRef object to be in a string format.

How do i convert the SecKeyRef object to nsstring object?

nikita21
  • 111
  • 1
  • 5

3 Answers3

5
// you have SecKeyRef keyref from somewhere 
size_t keySize = SecKeyGetBlockSize(keyref);
NSData* keyData = [NSData dataWithBytes:keyref length:keySize];

Then use this NSData category to encode the NSData object with base64 to a NSString.

NSString *keyStringB64 = [keyData base64EncodedString];
Or Arbel
  • 2,965
  • 2
  • 30
  • 40
orkoden
  • 18,946
  • 4
  • 59
  • 50
  • 1
    Does this really work? Has anyone tried it? Do you get the correct data by passing a `SecKeyRef` for the bytes? I have a hard time believing this. – Codo Jan 04 '15 at 12:40
  • 5
    No, It does not work for the public key specifically, you need to parse the key modules to get the real public key as a string. Apple has an example of this here: https://developer.apple.com/library/ios/samplecode/CryptoExercise/Introduction/Intro.html – James Jones Feb 03 '15 at 22:34
0
+ (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;
}

then, conver the data to base64 string.

it works fine when I run this code as part of an iOS app.

see iOS SecKeyRef to NSData

see more https://developer.apple.com/library/archive/samplecode/CryptoExercise/Introduction/Intro.html

0

[Cleanup of old question]

Saving SecKeyRef device generated public/private key pair on disk

Shows how to create an NSData object. As I'm no iOS developer, I'll leave the conversion to a string (e.g. using base 64 encoding) as an excercise.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263