Encrypt iOS Elliptic Curve Private Key

I'm developing an iOS Framework based on Objective-C that needs to generate Elliptic Curve KeyPair by Software, in order to retrieve the PrivateKey, encrypt and store it. This PrivateKey is used later to sign (with the SecKeyRawSign method) and the signature will be sent back to the server, where will be checked with the PublicKey.


To achieve the generation I'm using the Keychain (not the Secure Enclave), in this way I'm able to retrieve both Key also as CFDataRef.

Now I need to encrypt the PrivateKey, and I can't just encrypt the entire byte array, otherwise when I will try to decrypt it with a wrong password, I will not be able to reconstruct anywhere the Key, and the sign method will fail, exposing me to offline attacks. What I'm saying is that, when I will decrypt the Key, I would like to receive a well format key, but obviously not the correct one, so I can generate a signature and delegate to the server the verification and how to handle the error.


So, how can I encrypt this byte array of the PrivateKey?

Everything is already implemented, also the encryption and decryption methods, I need just to extract "a part" of the PrivateKey and encrypt just that, but how can I do this?

Replies

I’m confused by your goals here. You wrote:

I [need] to generate Elliptic Curve KeyPair by Software, in order to retrieve the PrivateKey, encrypt and store it.

Where are you planning to store this private key? In general I recommend that you store private keys in the keychain, so extract the key, encrypting it yourself, and then storing it elsewhere is a bit weird. Clearly I’m missing some context here. Can you elaborate?

Also, just in case you missed it:

  • iOS 10 added new APIs to encrypt and decrypt with asymmetric keys, so you should avoid

    SecKeyRawSign
    unless you have to support iOS 9.
  • iOS 10 also supports new APIs to import and export asymmetric keys, which means that you don’t have to run keys through the keychain just to get at the raw bits.

To learn more about this open up

<Security/SecKey.h>
and search for
__IOS_AVAILABLE(10.0)
.

Share and Enjoy

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

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

Doesn't matter, I plan to store again on keychain encrypted.

The idea is to encrypt the private key with a password, and later, to verify the password, try to decrypt the private key, generate a signature e send back to the server, that will reply with the result of the check. A fail will mean that the password was incorrect, but in this way I don't have to check the password on mobile side, avoiding offline attacks

The idea is to encrypt the private key with a password, and later, to verify the password, try to decrypt the private key, generate a signature e send back to the server, that will reply with the result of the check.

Is this a standard security algorithm? Or something you’ve designed yourself? If it’s the latter I strongly recommend you get a crypto expert to review it. Not being a crypto expert myself, I’m very suspicious of any ‘home grown’ crypto designs.

Regardless, the answer to your question is clear: when you export an EC key via

SecKeyCopyExternalRepresentation
, the data is in a very specific format (ANSI X9.63). iOS does not have any public APIs for parsing or formatting such data. If you want to do that you’ll have to write your own code for it.

Share and Enjoy

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

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