Import PKCS#12 into macOS login keychain or system keychain

Hello. I want to do the following and need your help.

  1. I want to import a certificate (pkcs#12) into my macOS keychain with a setting that prohibits exporting the certificate.
  2. I want to import the certificate (pkcs#12) into my login keychain or system keychain.

I was able to achieve [1] with the help of the following threads, but have the following problems.

https://developer.apple.com/forums/thread/677314?answerId=824644022#824644022

  • how to import into login keychain or system keychain
  • How to achieve this without using the deprecated API

To import into the login keychain, I could use the “SecKeychainCopyDefault” function instead of the “SecKeychainCopySearchList” function, However, both of these functions were deprecated APIs.

https://developer.apple.com/documentation/security/seckeychaincopysearchlist(_:)

https://developer.apple.com/documentation/security/seckeychaincopydefault(_:)

I checked the following URL and it seems that using the SecItem API is correct, but I could not figure out how to use it.

https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains

Is there any way to import them into the login keychain or system keychain without using these deprecated APIs?

… with a setting that prohibits exporting the certificate.

You mean the private key, right? The certificate is fancy wrapper around the public key associated with that private key, so being unable to export the certificate would be problematic O-:

I think you’re mixing up certificate and digital identity. That difference is something I’ve covered in many different places. Probably the most coherent is the one in TN3161 Inside Code Signing: Certificates, although if you’re coming at this from a TLS perspective then I recommend TLS for App Developers.

TN3137 explains the difference between the file-based keychain and the data protection keychain. Keeping that in mind, are you sure you want to read this into the file-based keychain? The data protection keychain is, in general, the better option.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

TN3137 explains the difference between the file-based keychain and the data protection keychain. Keeping that in mind, are you sure you want to read this into the file-based keychain? The data protection keychain is, in general, the better option.

Thanks for the reply. You are right, it is a private key.

I generally understand that data protection keychains are better option, but I would like to know how to import them into a file-based keychain (login keychain or system keychain) without using a deprecated API.

I would like to know how to import them into a file-based keychain … without using a deprecated API.

I wanna be clear about something here. While certainly keychain APIs are deprecated, that’s not the whole story. The important point is that the file-based keychain is deprecated as a whole. We’ve deprecated certain APIs because they only make sense when using the file-based keychain. If we could deprecate the SecItem API we would, but we can’t because that API is also used to access the data protection keychain.

So, avoiding these deprecated APIs while continuing to use the file-based keychain is missing the point.

However, it’s certainly possible. On macOS the SecPKCS12Import routine will import the digital identity into the default file-based keychain by default [1].

Unfortunately this API doesn’t let to specify the extractable flag. You may be able to set that after the import by calling SecItemUpdate with the kSecAttrIsExtractable attribute. I’ve never actually tried that.

If that doesn’t work then you have to use SecItemImport, and that requires that you supply a keychain, which you can only get using one of our deprecated APIs.

login keychain or system keychain

SecPKCS12Import targets the default keychain, as returned by SecKeychainCopyDefault. The keychain you get varies based on your execution context:

  • In some contexts, like an app, that’s typically the login keychain.

  • In other contexts, like a launchd daemon, that’s typically the system keychain.

Note I say “typically” because the user can configure this.

There’s no way to import or add items to a non-default keychain without using deprecated API.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] On macOS 15 you can opt out of that via kSecImportToMemoryOnly.

The important point is that the file-based keychain is deprecated as a whole.

I was not aware that the entire file-based keychain is already officially deprecated.

If the file-based keychain is to be deprecated, I would like to know how to import it into the data protection keychain in a way that prohibits the export of private keys.

Import PKCS#12 into macOS login keychain or system keychain
 
 
Q