Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot figure out how to publish public key generated on iPhone

I am using the commoncrypto library on the iPhone to create a pair of RSA keys and I am trying to send the public key to a server (Python) so that I can use it to verify a signature sent from the phone.

I'm using the exact code from the CommonCrypto example using the method getPublicKeyBits() which looks like this:

`- (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;

}`

The problem is that I don't know how, exactly, the key is being stored or how to pass it. I am using the getPublicKeyBits() to get it in a NSData structure, and I've imported a library to encode it in base64. I'm getting a key (SHA1, I'd like to move to SHA256, but that's secondary to getting this working) and the base64 version looks like other keys I've found here and in other people solving RSA problems.

I've been trying to use the M2Crypto library in Python and when I try to verify I'm getting the error "RSA Error: No Start Line". Here's the code I'm using to receive the public key:

pubKey = request.form['publickey']

uid = uuid4().hex
while not unique(uid, User):
    uid = uuid.uuid4().hex
user = User(uid, email, secret, pubKey)

And the code I'm using to check the signature:

def validate(sessionKey, sig, pem):
    bio = BIO.MemoryBuffer(pem.encode('ascii'))
    rsa = RSA.load_pub_key_bio(bio)
    pubkey = EVP.PKey()
    pubkey.assign_rsa(rsa)

    pubkey.reset_context(md='sha1')
    pubkey.verify_init()
    pubkey.verify_update(sessionKey)

    return pubkey.verify_final(sig)

I'm really stumped as to what I'm doing wrong but I feel like I'm getting close. If my whole method is not the way you'd do it, I'd love to hear any other way to generate RSA keys on the phone, publish the public key to a server, and then verify a signature from the phone on that server.

Thanks!

like image 367
brennen Avatar asked Apr 16 '12 03:04

brennen


1 Answers

You can use the getPublicKeyBits method from SecKeyWrapper in the Apple CryptoExercise code

https://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_h.html

This will get you the DER encoded binary data. Then use the following method to load it into M2Crypto in Python: (Basically, just base64 it and invoke one method.)

https://stackoverflow.com/a/5765576/584616

I have an ARC enabled version of this getPublicKeyBits method, but I haven't gotten around to posting it yet.

Update - on re-reading your question, the answer is actually here:

How to find out the modulus and exponent of RSA Public Key on iPhone/Objective C

You can use this to get the modulus and exponent as NSData, which you should be able to easily convert into base64 or your representation of choice.

like image 118
StCredZero Avatar answered Oct 26 '22 23:10

StCredZero