Unable to figure out how to publish the public key created on the iPhone.

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

I am using the exact code from the CommonCrypto example using the getPublicKeyBits() method, 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 the key is actually stored or how to transfer it. I use getPublicKeyBits() to get it in the NSData structure, and I imported the library to encode it in base64 . I get the key (SHA1, I would like to switch to SHA256, but this is secondary for getting this working), and the base64 version looks like other keys that I found here and with other people who solve RSA problems.

I try to use the M2Crypto library in Python, and when I try to verify that I get the error "RSA Error: No Start Line" . Here is the code that I use to get 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 that I use to verify 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 am very fixated on what I am doing wrong, but I feel that I am approaching. If my method is not the way you did it, I would like to hear any other way to create RSA keys on the phone, publish the public key on the server and then verify the signature from the phone on this server.

Thanks!

+6
source share
2 answers

You can use getPublicKeyBits method from SecKeyWrapper in Apple CryptoExercise code

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

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

fooobar.com/questions/913287 / ...

I have a version of this getPublicKeyBits method that supports ARC, but I haven't posted it yet.

Refresh - when you read your question again, the answer is actually here:

How to find out the RSA public key module and exponent on iPhone / Goal C

You can use this to get a module and metric like NSData, which you can easily convert to base64 or your choice representation.

+1
source

The main implementation of M2Crypto is OpenSSL. OpenSSL will not import your public key when it is exported, but only if it is "embedded" in a possibly self-signed certificate. Check out how to create a self-signed certificate using the Common Crypto or Security framework, deploy your public key and sign it using your private key, extract its data and send it to your server: it should work.

See also openssl_pkey_get_public do not open the public key, "no start line" error (second answer)

0
source

Source: https://habr.com/ru/post/913286/


All Articles