Generate key pair on iphone and print to log as NSString
Asked Answered
T

3

6

Following Apple example code in: http://developer.apple.com/library/ios/#documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html

I'm able to successfully generate key-pair with the code snippet below, but unable to print the keys...

The function SecKeyGeneratePair() - returns the keys as SecKeyRef type.

I have no idea how to handle this type, I understand that this is the keychain representation but how can I actually view the key-pair as NSString?? More specifically, how to convert SecKeyRef to NSString??

static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey\0";
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey\0";
                                                            // 1


- (void)generateKeyPairPlease
{
    OSStatus status = noErr;
    NSMutableDictionary *privateKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *publicKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *keyPairAttr = [[NSMutableDictionary alloc] init];
                                                                // 2

    NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier
                                length:strlen((const char *)publicKeyIdentifier)];
    NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier
                               length:strlen((const char *)privateKeyIdentifier)];
                                                                // 3

    SecKeyRef publicKey = NULL;
    SecKeyRef privateKey = NULL;                                // 4

    [keyPairAttr setObject:(id)kSecAttrKeyTypeRSA
                                   forKey:(id)kSecAttrKeyType]; // 5
    [keyPairAttr setObject:[NSNumber numberWithInt:1024]
                             forKey:(id)kSecAttrKeySizeInBits]; // 6

    [privateKeyAttr setObject:[NSNumber numberWithBool:YES]
                               forKey:(id)kSecAttrIsPermanent]; // 7
    [privateKeyAttr setObject:privateTag
                            forKey:(id)kSecAttrApplicationTag]; // 8

    [publicKeyAttr setObject:[NSNumber numberWithBool:YES]
                               forKey:(id)kSecAttrIsPermanent]; // 9
    [publicKeyAttr setObject:publicTag
                            forKey:(id)kSecAttrApplicationTag]; // 10

    [keyPairAttr setObject:privateKeyAttr
                               forKey:(id)kSecPrivateKeyAttrs]; // 11
    [keyPairAttr setObject:publicKeyAttr
                                forKey:(id)kSecPublicKeyAttrs]; // 12

    status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr,
                                      &publicKey, &privateKey); // 13
//    error handling...


    if(privateKeyAttr) [privateKeyAttr release];
    if(publicKeyAttr) [publicKeyAttr release];
    if(keyPairAttr) [keyPairAttr release];
    if(publicKey) CFRelease(publicKey);
    if(privateKey) CFRelease(privateKey);                       // 14
}
Toinette answered 8/4, 2012 at 17:16 Comment(1)
Not able to generate keys pair...It is giving value for OSStatus status -34018Supporter
O
7

You can use SecItemCopyMatching to get key's NSData. Check getPublicKeyBits method in Apple's CryptoExercise, it implements exactly what you need.

Then you can convert NSData to a string. Perhaps, Base64 encoding will suite your needs. Here you can find Base64 encoding/decoding sample for iPhone. Alternatively, this answer may also be useful for Base64 encoding.

Ogawa answered 8/4, 2012 at 18:49 Comment(3)
thank you, I use the getPublicKeyBits and I do receive the value as NSData, there is something weird though, when creating the keypair I specify kSecAttrKeySizeInBits = 1024, but the NSData size (received from getPublicKeyBits) is 140 bytes (instead of the expected 128) any idea why??Toinette
This is probably due to the format that is used to store keys. I'm not sure what is the reason you're printing the keys. Checkout this and this links that discuss ways to work with iOS keys.Ogawa
I can get the NSData and generate a NSString use: [data base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength]; [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];. But can not use this NSString to encrypt . SOSSapers
S
2

You can use https://github.com/henrinormak/Heimdall

let localHeimdall = Heimdall(tagPrefix: "com.example")

if let heimdall = localHeimdall {
    let publicKeyData = heimdall.X509PublicKey()
    var publicKeyString = publicKeyData.base64EncodedStringWithOptions(.allZeros)

    // If you want to make this string URL safe,
    // you have to remember to do the reverse on the other side later
    publicKeyString = publicKeyString.stringByReplacingOccurrencesOfString("/", withString: "_")
    publicKeyString = publicKeyString.stringByReplacingOccurrencesOfString("+", withString: "-")

    println(publicKeyString) // Something along the lines of "MIGfMA0GCSqGSIb3DQEBAQUAA..."

    // Data transmission of public key to the other party
}

swift 3:

let localHeimdall = Heimdall(tagPrefix: "com.example")
if let heimdall = localHeimdall, publicKeyData = heimdall.publicKeyDataX509() {

    var publicKeyString = publicKeyData.base64EncodedString()

    // If you want to make this string URL safe,
    // you have to remember to do the reverse on the other side later
    publicKeyString = publicKeyString.replacingOccurrences(of: "/", with: "_")
    publicKeyString = publicKeyString.replacingOccurrences(of: "+", with: "-")

    println(publicKeyString) // Something along the lines of "MIGfMA0GCSqGSIb3DQEBAQUAA..."

    // Data transmission of public key to the other party
}
Shipmaster answered 7/7, 2015 at 11:14 Comment(0)
A
0
-(void)writePublicKeyModAndExp
{
  KeyHelper* keyHelper =[[KeyHelper alloc]init];
  NSData* pubkeyData=  [keyHelper getPublicKeyBitsWithtag:publicTag];

  NSLog(@"pubKey :%@",[pubkeyData base64Encoding]);

  NSData *modData=  [keyHelper getPublicKeyModFromKeyData:pubkeyData];
  NSLog(@"modulus :%@",[modData base64Encoding]);

  NSData *expoData=  [keyHelper getPublicKeyExpFromKeyData:pubkeyData];
  NSLog(@"exponent :%@",[expoData base64Encoding]);
}

You can find whole code here https://github.com/ozgurshn/EncryptionForiOS

Astrophysics answered 10/3, 2015 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.