How do I generate an RSA public key using a modulus and exponent in iOS? (Obj-C)

Hi guys,


I need to generate an RSA public key from a modulus and exponent and I'm unable to find any resources where someone has done this successfully. I can't even find a way to do it in Apples documentation.


I have heard using SecKeyRef and/or OpenSSL is the way to go but searches on both of those lead to nothing that has worked (and what I tried is far too extensive to list here). Is this something not possible in iOS? If anyone has any ideas how to accomplish this I would greatly appreciate hearing them. Thank you.

Accepted Reply

iOS does not provide any public APIs for this. You'll need to write or acquire the necessary code. You can do it with a full-featured security toolkit, like OpenSSL, or just hack something together (this is a relatively simple use of ASN.1).


What I recommend is that you restructure your system so that you don't require this. Most folks who have this problem are getting the modulus and exponent from a server that has a full-featured security toolkit (OpenSSL, something Java-ish, and so on). In that case you can have the server build the public key and send you that. Or, to make things even easier, have the server put the public key into a certificate, which is trivial to work with on iOS.


Share and Enjoy

--

Quinn "The Eskimo!"

Apple Developer Relations, Developer Technical Support, Core OS/Hardware

Replies

iOS does not provide any public APIs for this. You'll need to write or acquire the necessary code. You can do it with a full-featured security toolkit, like OpenSSL, or just hack something together (this is a relatively simple use of ASN.1).


What I recommend is that you restructure your system so that you don't require this. Most folks who have this problem are getting the modulus and exponent from a server that has a full-featured security toolkit (OpenSSL, something Java-ish, and so on). In that case you can have the server build the public key and send you that. Or, to make things even easier, have the server put the public key into a certificate, which is trivial to work with on iOS.


Share and Enjoy

--

Quinn "The Eskimo!"

Apple Developer Relations, Developer Technical Support, Core OS/Hardware

Thank you so much for the response.


Would I be correct in assuming that:


1. The server would send a certificate in a .pem or .der format continaing the public key.


2. My app would use the SecKey functions as shown in this document to save the key sent in that certificate to the keychain : https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW9

3. I'd sign my data using the public key I stored in the keychain.


4. Send the data on its merry way.



Sorry for the long question I'm completely new to cryptography and overwhelmed and am trying to find a high level overview I can then later break down into pieces to solve.

The server would send a certificate in a .pem or .der format continaing the public key.

Yes. DER format would be easier because you can pass the data directly to

SecCertificateCreateWithData
.

My app would use the SecKey functions as shown in this document to save the key sent in that certificate to the keychain

You could do this but it's not required; you can get the public key from the certificate, even when it's not in the keychain, using

SecTrustCopyPublicKey
. I described how to do this in this post on the old DevForums.

Note that putting a certificate or public key in the keychain is possible but rarely necessary and, in situations where it's optional, there's no benefit to it. The keychain is about storing secrets, and public keys aren't secret.

I'd sign my data using the public key I stored in the keychain.

Huh? When you sign data you're supposed to use the private key; that's the only way things make sense (the signature proves that someone with access to the private key signed the data).

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks so much!


And I mistakenly used the wrong terminology here:

I'd sign my data using the public key I stored in the keychain.

Huh? When you sign data you're supposed to use the private key; that's the only way things make sense (the signature proves that someone with access to the private key signed the data).


What I meant to say is "Encrypt my data using the public key". (Which according to what I've read is how it is supposed to work, "Bob encrypts his data with Alice's public key").

What I meant to say is "Encrypt my data using the public key". (Which according to what I've read is how it is supposed to work, "Bob encrypts his data with Alice's public key").

Yes.

If you're ever unclear on this, check out the header docs in

<Security/SecKey.h>
. For example,
SecKeyEncrypt
says that
key
parameter is the "Public key with which to encrypt the data.", while
SecKeyRawSign
says "Private key with which to sign."

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you so much! This was a huge help.

Know this is an old thread, but it's funny to find since the suggestion is "don't require that" but with Sign In with Apple, it's now required that we do this since you're providing the public JWK and we thus need to take the modulus and exponent and convert it manually.