What is the difference between Cryptokit keys and normal keys?

Hi,


I want to know the difference between private keys generated using Cryptokit framework and normal key pair generation.


Cryptokit framework documentation link is

https://developer.apple.com/documentation/cryptokit/performing_common_cryptographic_operations


Normal key pair generation link is

https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/generating_new_cryptographic_keys


In both cases i am creating keys of type p256.


The sample code for both is given below.


//Private key using Cryptokit framework
let signinKey = P256.Signing.PrivateKey()


//Private key using normal keypair generation
let attributes: [String: Any] = [
    kSecClass as String: kSecClassKey,
    kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeySizeInBits as String: 256,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String: true,
        kSecAttrLabel as String:"test",
        kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked,
        kSecUseDataProtectionKeychain: true,
        kSecAttrApplicationTag as String: "com.mydomian.uniqueTag"    ]
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
    throw error!.takeRetainedValue() as Error
}
  

Thanks in Advance for the help

Accepted Reply

The error log i am getting is -34018

This problem is almost certainly caused by you testing in a playground, which is missing the

com.apple.application-identifier
entitlement. You can the background to this in Troubleshooting -34018 Keychain Errors.

I recommend that you test in an app. If you’re targeting iOS, that should be sufficient. If you’re targeting macOS, you need to make sure you have the

com.apple.application-identifier
, which you don’t get by default. I usually trigger this by enabling keychain sharing but then don’t list any shared groups.

Share and Enjoy

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

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

Replies

I want to know the difference between private keys generated using Cryptokit framework and normal key pair generation.

I’m not sure what you’re asking here. In general, keys are keys, so it doesn’t matter how you generate them. Are you hitting some specific problem?

Share and Enjoy

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

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

Hi,


I have found the term "strongly typed cryptographic keys" while going through the page(storing cryptokit keys) https://developer.apple.com/documentation/cryptokit/storing_cryptokit_keys_in_the_keychain


Here it is said

"CryptoKit defines highly specific key types that embody a particular cryptographic algorithm and purpose. Some of these key types, like

P256.Signing.PrivateKey
, correspond to items that the Keychain Services API stores natively as
SecKey
instances."


But as you said "In general, keys are keys, so it doesn’t matter how you generate them. ",we can generate and store p256 keys(in keychain) using normal SecKeyCreateRandomKey while describing attribute like kSecAttrKeyType as kSecAttrKeyTypeECSECPrimeRandom and kSecAttrKeySizeInBits as 256.


But as per documentation said "For information about storing cryptographic keys that you create with the Apple CryptoKitframework, see Storing CryptoKit Keys in the Keychain." ,it is presumed that these keys are different not same though they are using same keyType.Their key generation process is also different as described in my question.

If you store a key in the keychain, you can work with that key using the

SecKey
type and its older APIs, or you can work with that key using CryptoKit. It’s the same key in both cases, it’s just a question of which API you’re using it with.

Share and Enjoy

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

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

Hi,

Thanks for the reply.

I want to use CryptoKit framework to generate the keys. So i use

let privateKeyValue = P256.Signing.PrivateKey()

to generate key. But the key is not stored in Keychain.


Can you please tell me how to store the keys with label name while generating the keys itself?

Can you please tell me how to store the keys with label name while generating the keys itself?

Have you looked at Storing CryptoKit Keys in the Keychain?

Share and Enjoy

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

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

Hi,


I checked the link Storing CryptoKit Keys in the Keychain.


I ran the sample using Xcode. In the simulator i checked the code. In the simulator I checked (Using Test Button for the purpose signing).It is giving pass result. But when i checked the keychain,there is no key (generated by this).So i created one new satndalone application just for testing without use of any type of simulator.But I got error.(Unable to store the item.)I posted that question in the forum already (link of the thread is https://forums.developer.apple.com/thread/123674).

The code is given below

import Cocoa
import Foundation
import CryptoKit
import Security

/// An error we can throw when something goes wrong.
struct KeyStoreError: Error, CustomStringConvertible {
    var message: String

    init(_ message: String) {
        self.message = message
    }

    public var description: String {
        return message
    }
}

/*
extension OSStatus {

    /// A human readable message for the status.
    var message: String {
        return (SecCopyErrorMessageString(self, nil) as String?) ?? String(self)
    }
}
*/

/// The interface needed for SecKey conversion.
protocol SecKeyConvertible: CustomStringConvertible {
    /// Creates a key from an X9.63 representation.
    init<Bytes>(x963Representation: Bytes) throws where Bytes: ContiguousBytes

    /// An X9.63 representation of the key.
    var x963Representation: Data { get }
}

extension SecKeyConvertible {
    /// A string version of the key for visual inspection.
    /// IMPORTANT: Never log the actual key data.
    public var description: String {
        return self.x963Representation.withUnsafeBytes { bytes in
            return "Key representation contains \(bytes.count) bytes."
        }
    }
}
// Assert that the NIST keys are convertible.
extension P256.Signing.PrivateKey: SecKeyConvertible {}
extension P256.KeyAgreement.PrivateKey: SecKeyConvertible {}
let keyValue = P256.Signing.PrivateKey();
func storeKey<T: SecKeyConvertible>(_ key: T, label: String) throws {

     // Describe the key.
     let attributes = [kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
                       kSecAttrKeyClass: kSecAttrKeyClassPrivate] as [String: Any]

     // Get a SecKey representation.
     guard let secKey = SecKeyCreateWithData(key.x963Representation as CFData,
                                             attributes as CFDictionary,
                                             nil)
         else {
             throw KeyStoreError("Unable to create SecKey representation.")
     }

     // Describe the add operation.
     let query = [kSecClass: kSecClassKey,
                  kSecAttrApplicationLabel: label,
                  kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked,
                  kSecUseDataProtectionKeychain: true,
                  kSecValueRef: secKey] as [String: Any]

     // Add the key to the keychain.
     let status = SecItemAdd(query as CFDictionary, nil)
     guard status == errSecSuccess else {
         throw KeyStoreError("Unable to store item:")
     }
}

storeKey(keyValue, label:"test.sample.com")


The error log i am getting is

-34018

Playground execution terminated: An error was thrown and was not caught:

▿ Unable to store item:

- message : "Unable to store item:"


So can you please help me on this?

The error log i am getting is -34018

This problem is almost certainly caused by you testing in a playground, which is missing the

com.apple.application-identifier
entitlement. You can the background to this in Troubleshooting -34018 Keychain Errors.

I recommend that you test in an app. If you’re targeting iOS, that should be sufficient. If you’re targeting macOS, you need to make sure you have the

com.apple.application-identifier
, which you don’t get by default. I usually trigger this by enabling keychain sharing but then don’t list any shared groups.

Share and Enjoy

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

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