I downloaded a P12 file (containing a private key) from the company server, and retrieved the private key from this P12 file using a password :
private func loadPrivateKeyFromPKCS12(path: String, password: String) throws -> SecKey? {
let p12Data: Data
do {
p12Data = try Data(contentsOf: fileURL)
} catch let readError {
...
}
let options: [CFString: Any] = [
kSecImportExportPassphrase: password as CFString
]
var items: CFArray?
let status = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items)
guard status == errSecSuccess else {
throw exception
}
var privateKey: SecKey?
let idd = identity as! SecIdentity
let _ = SecIdentityCopyPrivateKey(idd, &privateKey)
return privateKey
}
However, when I use this private key to call SecKeyCreateSignature for data signing, a dialog box always pops up to ask user to input the Mac admin password.
What confuses me is that this private key is clearly stored in the local P12 file, and there should be no access to the keychain involved in this process. Why does the system still require the user's login password for signing?
Is it possible to perform silent signing (without the system dialog popping up) in this scenario?
this private key is clearly stored in the local P12 file
That’s not the caes, at least on macOS. SecPKCS12Import behaves differently on iOS and macOS:
- On iOS it imports the PKCS#12 file and gives you back an in-memory digital identity.
- On macOS, it defaults to importing the PKCS#12 file to the default keychain, and gives you back a digital identity that references that keychain.
If you want the iOS behaviour on macOS, you have to opt it to that by setting kSecImportToMemoryOnly.
Having said that, I’m not sure that continuing to re-import the file is the right option. In general, it’s better to store secrets in the keychain rather than in a .p12 file on disk. But that raises the question of which keychain. I generally recommend the data protection keychain, in which case the path forward is:
- Get an in-memory digital identity.
- Call
SecItemAddwith thekSecUseDataProtectionKeychainto add it to the data protection keychain.
For a detailed explanation of these subtleties, see TN3137 On Mac keychain APIs and implementations.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"