7 Replies
      Latest reply on Oct 13, 2019 5:11 AM by eskimo
      prabalNet Level 1 Level 1 (0 points)

        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

        • Re: What is the difference between Cryptokit keys and normal keys?
          eskimo Apple Staff Apple Staff (12,015 points)

          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"

            • Re: What is the difference between Cryptokit keys and normal keys?
              prabalNet Level 1 Level 1 (0 points)

              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.

                • Re: What is the difference between Cryptokit keys and normal keys?
                  eskimo Apple Staff Apple Staff (12,015 points)

                  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"

                    • Re: What is the difference between Cryptokit keys and normal keys?
                      prabalNet Level 1 Level 1 (0 points)

                      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?

                        • Re: What is the difference between Cryptokit keys and normal keys?
                          eskimo Apple Staff Apple Staff (12,015 points)

                          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"

                            • Re: What is the difference between Cryptokit keys and normal keys?
                              prabalNet Level 1 Level 1 (0 points)

                              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?

                                • Re: What is the difference between Cryptokit keys and normal keys?
                                  eskimo Apple Staff Apple Staff (12,015 points)

                                  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"