SecItemCopyMatching仅在iPhone 13 Pro Max上返回errSecItemNotFound(-25300)问题求助
Hey there, let's tackle this frustrating device-specific keychain issue. I've run into similar quirks with EC key queries on certain iOS models, and the root cause almost always boils down to mismatched or missing key attributes between how you stored the key and how you're querying for it. Here's how to adjust your code and troubleshoot:
Common Causes & Fixes for iPhone 13 Pro Max
1. Explicitly Specify Key Size (Critical for EC Keys)
Elliptic Curve keys rely on a specific bit length (usually 256 bits for ECSECPrimeRandom). If you included this attribute when storing the key, you must include it in your query too—some devices (like iPhone 13 Pro Max) enforce stricter attribute matching than others.
Add this line to your getquery dictionary:
kSecAttrKeySizeInBits as String: 256
2. Verify Access Group Consistency
If your app uses App Groups or shares keychain items across extensions, ensure your query includes the same kSecAttrAccessGroup value you used when storing the key. Even a tiny mismatch here will cause errSecItemNotFound on strict devices.
Uncomment and adjust this line if applicable:
// kSecAttrAccessGroup as String: "com.yourcompany.yourappgroup"
3. Include Persistence Attribute (If Applicable)
If you stored the key as a permanent item (using kSecAttrIsPermanent: true), add this to your query to narrow results to persistent keys:
kSecAttrIsPermanent as String: true
4. Simplify Query to Isolate the Issue
If the above fixes don't work, strip down your query to the bare minimum first to confirm the key exists:
let getquery: [String: Any] = [ kSecClass as String: kSecClassKey, kSecAttrApplicationTag as String: serviceName, kSecReturnRef as String: true ]
If this works, gradually add back attributes (key type, size, etc.) until you find which one is causing the mismatch.
Modified Code with Fixes
Here's your updated function with the key adjustments:
func signString(clearString: String) -> Bool { let getquery: [String: Any] = [ kSecClass as String: kSecClassKey, kSecAttrApplicationTag as String: serviceName, kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, // Added EC key size // kSecAttrAccessGroup as String: "your.app.group.id", // Uncomment if using app groups kSecReturnRef as String: true ] var item: CFTypeRef? let status = SecItemCopyMatching(getquery as CFDictionary, &item) if status != errSecSuccess { print("No key found, status code: \(status)") // Print code for deeper debugging return false } else { guard let key = item as? SecKey else { print("Failed to cast item to SecKey") return false } self.privateKey = key print("key = ", key) guard let data = clearString.data(using: .utf8) as CFData? else { print("Failed to convert string to UTF-8 data") return false } let algorithm: SecKeyAlgorithm = .ecdsaSignatureMessageX962SHA256 guard SecKeyIsAlgorithmSupported(key, .sign, algorithm) else { print("Algorithm Not Supported") return false } var error: Unmanaged<CFError>? guard let signature = SecKeyCreateSignature(key, algorithm, data, &error) as Data? else { let errorMsg = error?.takeRetainedValue().localizedDescription ?? "Unknown signature error" print("signature error: \(errorMsg)") return false } self.signedString = signature.base64EncodedString() return true } }
Additional Troubleshooting Steps
- Check Your Key Storage Code: Ensure the attributes you used to store the private key exactly match your query attributes. Even a single missing or mismatched attribute will break matching on strict devices.
- Inspect Keychain Items: Use Apple's Keychain Viewer or third-party tools on the iPhone 13 Pro Max to view the actual attributes of your stored key—this will reveal any mismatches.
- Validate
serviceName: Make sureserviceNameis identical across all devices (no dynamic values that change per device).
内容的提问来源于stack exchange,提问作者Hilal




