Generate private key that cannot be exported
Asked Answered
C

2

6

I want to generate a key pair on an iPhone such that the private key can only ever be used to sign blocks of data on that particular iPhone.

The SecKeyGeneratePair function looks promising. I can generate a key pair to the keychain (using kSecAttrIsPermanent) and I can disable decryption, derivation and unwrapping with the private key (setting kSecAttrCanDecrypt, kSecAttrCanDerive and kSecAttrCanUnwrap to false).

Two things worry me about key pairs generated with SecKeyGeneratePair:

  1. Is it possible to export the private key outside of the keychain into application memory?

  2. Is it possible to change a key property (e.g. set kSecAttrCanDecrypt to true) after a private key has been created?

Cytosine answered 13/9, 2015 at 14:43 Comment(0)
D
5

This article provides more details (compared to other answers in this thread):

SecGenerateKeyPair(), which is used to generate RSA and ECDSA key pairs, can now be configured to directly store the generated private key in the device’s Keychain (within the Secure Enclave). This means that the private key can be used without ever leaving the device’s Secure Enclave.

And the important addition:

The kSecAttrTokenIDSecureEnclave attribute needs to be used when generating the key pair.

If you don't specify this attribute the private key will be accessible even on iOS9.

Disenchant answered 13/10, 2015 at 8:22 Comment(1)
Things work properly with RSA, but then kSecAttrTokenIDSecureEnclave and kSecAccessControlPrivateKeyUsage can't be specified. kSecAttrTokenIDSecureEnclave may not work with RSA key pairs.Cytosine
C
4

To answer the first question, the private key cannot be retrieved according to this source:

One API call, SecKeyGeneratePair(), creates a public and private key. The public key is returned to the app, and the private key is sent directly to the Secure Enclave. This private key cannot be retrieved.

More information is available here:

The supported keys are Elliptic Curve P256, the private key is not extractible in any form, even protected, and the applications are RawSign and RawVerify.

Cytosine answered 13/9, 2015 at 14:46 Comment(6)
The key type Elliptic Curve P256 (kSecAttrKeyTypeEC) seems to be one of several (8) supported key types that can be generated and the signing is based on the key type. The presentation at this point mentions Elliptic Curve P256 is presenting a use-case of remote authentication with TouchID, it is not clear that only Elliptic Curve P256 is supported even in this scenario.Chuipek
Do you have a link to all 8 supported key types?Cytosine
I have concerns about the private key upon generation. It seems that it is sent to the keychain if the attribute is kSecAttrIsPermanent is true. It also appears that upon return both the public and private keys are available via the SecKeyRef *publicKey and *privateKey pointers to the keychain items.Chuipek
These types can be found in the Security.framework include file SecItem.h. They are:kSecAttrKeyTypeRSA kSecAttrKeyTypeDSA kSecAttrKeyTypeAES kSecAttrKeyType3DES kSecAttrKeyTypeRC4 kSecAttrKeyTypeRC2 kSecAttrKeyTypeCAST kSecAttrKeyTypeEC.Chuipek
For documentation see SecKeyGeneratePair. I'm unclear of the relationship of the symmetric types and SecKeyGeneratePair.Chuipek
Does anyone know if private key data stored in the secure enclave is retrievable with keychain-dumper? Also, if kSecAttrTokenIDSecureEnclave isn't specified, will the private key be stored in the keychain database file? I've tried SecKeyGeneratePair with and without the kSecAttrTokenIDSecureEnclave attribute, and in both cases the keychain database file size remained unchanged.Francie

© 2022 - 2024 — McMap. All rights reserved.