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!