Post

Replies

Boosts

Views

Activity

Reply to Client certificate using CryptoKit
Right, so I did some more experimenting with both of the keys. Transforming the SecureEnclave key into a SecKey will always generate a new private key in the Secure Enclave, causing the initial Secure Enclave key and the SecKey to be non identical: let privateKey = try SecureEnclave.P256.Signing.PrivateKey() let attributes: [CFString: Any] = [ kSecClass: kSecClassKey, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrTokenID: kSecAttrTokenIDSecureEnclave ] let secKey = SecKeyCreateWithData(privateKey.dataRepresentation as CFData, attributes as CFDictionary, nil) // let secKey = SecKeyCreateWithData(Data() as CFData, attributes as CFDictionary, nil) Interestingly enough, it doesn't really matter what Data you provide to the SecKeyCreateWithData function when you set the kSecAttrTokenID field, odd... We do however get a valid SecKey reference which can be used, but as mentioned, it's a different one from the privateKey we created before. I checked this by comparing the public keys of both of these private keys, which do not match. Now, normally speaking, the SecKeyCopyExternalRepresentation function will result in an error for Secure Enclave SecKey objects, which makes sense, it's a non extractable key, but the SecureEnclave enum exposes the Data through the dataRepresentation. This appears to simply be an ASN.1 octet stream containing the X9.62 export of the actual Secure Enclave private key. So I decided to do some more digging and found out that we can get the same data through from the SecKey, only at key generation time. let attributes: [CFString: Any] = [ kSecClass: kSecClassKey, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrTokenID: kSecAttrTokenIDSecureEnclave ] let secKey = SecKeyCreateRandomKey(attributes as CFDictionary, nil) let secAttributes = (SecKeyCopyAttributes(secKey!) as! [CFString: Any]) let secBytes = secAttributes["toid" as CFString] as! Data let privateKey = try SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: secBytes) The toid field is available right after we create the key. It exposes the same data as the SecureEnclave enum (dataRepresentation) and we can actually create the SecureEnclave` key if we use this data. Now I end up with a couple more questions: Is there no way to convert a SecureEnclave key into a SecKey somehow? Is the dataRepresentation of the SecureEnclave insecure after all, as one can easily extract X9.62 data from it? (And therefor also the toid field in the attributes)? Is the toid field something I can use to continue (also in a production app)?
Topic: Programming Languages SubTopic: Swift Tags:
Jul ’23
Reply to Secure Enclave Cryptokit
[quote='841302022, DTS Engineer, /thread/786223?answerId=841302022#841302022'] It’s an opaque representation of the key. Internally this holds the key bytes, wrapped in a way that only the issuing SE can extract and work with the key. [/quote] Together with the potential fact that they're also tied to App ID entitlements, does this mean I can safely store this data representation in a file on disk or in the UserDefaults, or in an SQLite database of some sorts? I'm really curious, as the Keychain has several drawbacks to using it.
Topic: Privacy & Security SubTopic: General Tags:
May ’25
Reply to Navigation Title no longer showing for first Tab in iOS/iPadOS 26
It looks to me like there is an issue with the frame of the ScrollView. Applying a frame(maxWidth: .infinity) to a child of the ScrollView, fixes the issue. So this won't work: var body: some View { NavigationStack { VStack { ScrollView { Text("Hello, world") } } .navigationTitle(Text("Title")) .navigationSubtitle(Text("Subtitle")) } } But adding the frame modifier, fixes it: var body: some View { NavigationStack { VStack { ScrollView { Text("Hello, world") .frame(maxWidth: .infinity) // <-- resolves the issue } } .navigationTitle(Text("Title")) .navigationSubtitle(Text("Subtitle")) } } It appears it doesn't matter on which child you apply this "fix", it should just be on a child of the ScrollView.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25