SecuritySeniorOpen-ended

How do you generate and store a Themis key pair on iOS?

Explanation & Code

Answer: Generate the pair with TSKeyGen, then persist only the private key in the Keychain with a restrictive accessibility class and hand the public key to the server during enrolment. The private key must never reach UserDefaults, a plist, a log line, or an analytics event.

TSKeyGen(algorithm: .EC) returns 256-bit elliptic-curve keys, which are the sensible default — smaller and faster than the RSA option, with no practical security tradeoff. Store the raw Data rather than a Base64 string where you can; if the API forces Base64, remember the encoding adds no protection.

For a device-bound key you can go further and wrap the Themis private key with a Secure Cell sealed under a Keychain item that requires biometric presence, so the key is only usable after a successful Face ID or Touch ID check.

Code Example:

import themis
import Security

func enrol() throws -> Data {
    guard let pair = TSKeyGen(algorithm: .EC) else { throw CryptoError.keygen }

    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "client.private.key",
        kSecValueData as String: pair.privateKey as Data,
        // Never syncs to iCloud, unavailable until after first unlock.
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
    ]
    SecItemDelete(query as CFDictionary)
    guard SecItemAdd(query as CFDictionary, nil) == errSecSuccess else {
        throw CryptoError.keychain
    }

    return pair.publicKey as Data   // send to the server
}

Key Points:

  • Prefer .EC over .RSA — smaller keys, faster operations.
  • ...ThisDeviceOnly accessibility keeps the key out of iCloud Keychain and encrypted backups.
  • Keychain items survive app deletion; clear them on first launch if you want a fresh key per install.

Rate your understanding:

Ready to practice more Security?

Test yourself with our interactive quiz mode or browse all curated questions for this topic.