7

I've created a pair of keys using SecKeyGeneratePair. I'd now like to pass the public key to a server, but I'm not really sure how to proceed.

I have a function getPublicKeyBits (taken from Apple's CryptoExercise), but I don't really know what to do with the raw NSData. Here is the function:

- (NSData *)getPublicKeyBits {
    OSStatus sanityCheck = noErr;
    NSData* publicKeyBits = nil;
    NSData* publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
    CFDataRef cfresult = NULL;


    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*)&cfresult); 


    if (sanityCheck != noErr)
    {
        publicKeyBits = nil;
    }
    else 
    {
        publicKeyBits = (__bridge_transfer NSData *)cfresult;
    }

    return publicKeyBits;
}

How do I take this raw byte data and turn it into something like PEM or some other format that a crypto library understands? Should I base64 encode it? Are there other things I need to do as well?

If it helps, I'm trying to use the public key with the M2Crypto library available for Python.

Dr. Acula
  • 2,392
  • 4
  • 17
  • 17
  • No, it isn't BASE64. It is some ASN.1 structure containing a `SEQUENCE` with two `INTEGER` elements. While the second element seems to always be `65537` the other element seems to have the key size. But I still not have any idea how to get exponent and modulo out from them to export it to another format. – miho Mar 02 '14 at 14:58

2 Answers2

2

I think you will want to look at http://www.openssl.org/docs/crypto/pem.html# maybe:

int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                    unsigned char *kstr, int klen,
                                    pem_password_cb *cb, void *u);
Grady Player
  • 14,399
  • 2
  • 48
  • 76
  • 1
    That would mean including OpenSSL in my project. I've been doing everything with the built-in `CommonCrypto` library. It says in those linked docs that PEM is basically base64 encoding the key, and then wrapping it with header lines. I tried this, but I couldn't get it to work with `M2Crypto`. Are the bytes produced by the `getPublicKeyBits` function above in the correct "format" such that I can just base64 encode them? I apologize, I don't know much about cryptography and these standards and libraries. – Dr. Acula Apr 18 '12 at 17:28
  • it is a base64 of the DER version of the key... http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf – Grady Player Apr 18 '12 at 17:33
  • Ah, so it looks like `getPublicKeyBits` returns the bits `DER` encoded according to [this](http://stackoverflow.com/questions/3840005/how-to-find-out-the-modulus-and-exponent-of-rsa-public-key-on-iphone-objective-c). So if I base64 encode it and wrap the string with the header lines it should work. I tried this, but perhaps the code I used to base64 encode it was wrong. Thanks for the help! I'll mark this answer as correct, since it was very helpful. – Dr. Acula Apr 19 '12 at 20:49
  • Be wary of including use of openssl in iOS apps. It is, at best, discouraged by Apple. – Rich Everhart Jun 23 '15 at 17:29
1

This page has some great tips and sample code for packaging the data you have into the PEM format so you can send it to a server:

http://blog.wingsofhermes.org/?p=42

You don't need the whole openssl library compiled from source and statically linked to do it. I'm using just this technique, wrapping the base 64 key in "-----BEGIN PUBLIC KEY-----" and it can be read and used by a Rails application using the standard ruby openssl classes.

Matt Connolly
  • 9,757
  • 2
  • 65
  • 61