Security

RSS for tag

Secure the data your app manages and control access to your app using the Security framework.

Posts under Security tag

198 Posts

Post

Replies

Boosts

Views

Activity

Retrieving certificates from System Roots keychain
Hi there, I'm continuing to build up the API on keychain, I'm trying to implement the ability to create an own certificate chain for validation purposes, similar to ssl. To this extent I need to retrieve the certificates from the System's stores but I can't seem to find a way to do this in code? Creating a query with kSecMatchTrustedOnly only returns certificates which are seemingly manually marked as trusted or otherwise just skips over the System roots keychain. As far as I understand using kSecUseKeychain doesn't work either, since (besides SecKeychain being deprecated) it only works with SecItemAdd.
9
0
689
Dec ’24
Issue with Retrieving Updated Tokens from Keychain After Hard Reboot on Apple TV
In our application, we store user information (Username, Password, accessToken, Refresh token, etc.) in the keychain. However, after performing a hard reboot (unplugging and plugging back in), when we attempt to retrieve the ‘refresh token’ or ‘access token’ from the keychain, we receive the old token instead of the newly saved one.
4
0
636
Dec ’24
Deffie Hellman exchange for ECDH
I am trying to generate public and private keys for an ECDH handshake. Back end is using p256 for public key. I am getting a failed request with status 0 public func makeHandShake(completion: @escaping (Bool, String?) -> ()) { guard let config = self.config else { completion(false,APP_CONFIG_ERROR) return } var rData = HandshakeRequestTwo() let sessionValue = AppUtils().generateSessionID() rData.session = sessionValue //generating my ECDH Key Pair let sPrivateKey = P256.KeyAgreement.PrivateKey() let sPublicKey = sPrivateKey.publicKey let privateKeyBase64 = sPrivateKey.rawRepresentation.base64EncodedString() print("My Private Key (Base64): \(privateKeyBase64)") let publicKeyBase64 = sPublicKey.rawRepresentation.base64EncodedString() print("My Public Key (Base64): \(publicKeyBase64)") rData.value = sPublicKey.rawRepresentation.base64EncodedString() let encoder = JSONEncoder() do { let jsonData = try encoder.encode(rData) if let jsonString = String(data: jsonData, encoding: .utf8) { print("Request Payload: \(jsonString)") } } catch { print("Error encoding request model to JSON: \(error)") completion(false, "Error encoding request model") return } self.rsaReqResponseHandler(config: config, endpoint: config.services.handShake.endpoint, model: rData) { resToDecode, error in print("Response received before guard : \(resToDecode ?? "No response")") guard let responseString = resToDecode else { print("response string is nil") completion(false,error) return } print("response received: \(responseString)") let decoder = JSONDecoder() do { let request = try decoder.decode(DefaultResponseTwo.self, from: Data(responseString.utf8)) let msg = request.message let status = request.status == 1 ? true : false completion(status,msg) guard let serverPublicKeyBase64 = request.data?.value else { print("Server response is missing the value") completion(false, config.messages.serviceError) return } print("Server Public Key (Base64): \(serverPublicKeyBase64)") if serverPublicKeyBase64.isEmpty { print("Server public key is an empty string.") completion(false, config.messages.serviceError) return } guard let serverPublicKeyData = Data(base64Encoded: serverPublicKeyBase64) else { print("Failed to decode server public key from Base64. Data is invalid.") completion(false, config.messages.serviceError) return } print("Decoded server public key data: \(serverPublicKeyData)") guard let serverPublicKey = try? P256.KeyAgreement.PublicKey(rawRepresentation: serverPublicKeyData) else { print("Decoded server public key data is invalid for P-256 format.") completion(false, config.messages.serviceError) return } // Derive Shared Secret and AES Key let sSharedSecret = try sPrivateKey.sharedSecretFromKeyAgreement(with: serverPublicKey) // Derive AES Key from Shared Secret let symmetricKey = sSharedSecret.hkdfDerivedSymmetricKey( using: SHA256.self, salt: "AES".data(using: .utf8) ?? Data(), sharedInfo: Data(), outputByteCount: 32 ) // Storing AES Key in Config let symmetricKeyBase64 = symmetricKey.withUnsafeBytes { Data($0) }.base64EncodedString() print("Derived Key: \(symmetricKeyBase64)") self.config?.cryptoConfig.key = symmetricKeyBase64 AppUtils.Log(from: self, with: "Handshake Successful, AES Key Established") } catch { AppUtils.Log(from: self, with: "Handshake Failed :: \(error)") completion(false, self.config?.messages.serviceError) } } } this is request struct model public struct HandshakeRequestTwo: Codable { public var session: String? public var value: String? public enum CodingKeys: CodingKey { case session case value } public init(session: String? = nil, value: String? = nil) { self.session = session self.value = value } } This is backend's response {"message":"Success","status":1,"data":{"senderId":"POSTBANK","value":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErLxbfQzX+xnYVT1LLP5VOKtkMRVPRCoqYHcCRTM64EMEOaRU16yzsN+2PZMJc0HpdKNegJQZMmswZtg6U9JGVw=="}} This is my response struct model public struct DefaultResponseTwo: Codable { public var message: String? public var status: Int? public var data: HandshakeData? public init(message: String? = nil, status: Int? = nil, data: HandshakeData? = nil) { self.message = message self.status = status self.data = data } } public struct HandshakeData: Codable { public var senderId: String? public var value: String? public init(senderId: String? = nil, value: String? = nil) { self.senderId = senderId self.value = value } }
3
0
566
Dec ’24
How to Create a Designated Keychain for Testing Purposes?
I wrote a Keychain controller that add, delete and fetch keychain items using SecItemAdd(_:_:)and related APIs with data protection keychain enabled (kSecUseDataProtectionKeychain). I am using it in a macOS Cocoa app. I am using Swift Testing to write my tests to ensure that the controller works as expected. As I understand, I should create my own keychain for testing rather than use the actual keychain in macOS. Currently, I created a separate keychain group (e.g. com.testcompany.testapp.shared) and added it to myapp.entitlements file so that the tests pass without failing because of the missing entitlement file. SecKeychainCreate(_:_:_:_:_:_:) and SecKeychainDelete(_:) API are deprecated with no alternative provided in the documentation. I noticed SecKeychain class but documentation doesn't explain much about it. How should I test my keychain controller properly so that it does not use the actual macOS keychain, which is the "production" keychain?
3
0
632
Dec ’24
security commands coming from build runner yielding no results
I'm trying to sign a build coming from a gitlab runner, but for some reason security find-identity is yielding no results during the pipeline. Hitting the runner via SSH shows the results as I would expect, as well as VNCing into the runner and using the terminal. whoami on all 3 shows the same result My current attempt is to build the keychain on the fly so that I can ensure I have access to the identity, and it succeeds in building the keychain and importing the certs, but find-identity still shows zero results in the pipeline. - security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security list-keychains -d user -s "$KEYCHAIN_PATH" "/Users/######/Library/Keychains/login.keychain-db" "/Library/Keychains/System.keychain" - security set-keychain-settings "$KEYCHAIN_PATH" - security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security import "$SIGNING_KEY_DECODED" -P "$P12_PASSWORD" -A -f pkcs12 -k $KEYCHAIN_PATH -T "/usr/bin/codesign" - > # escape : CERT_IDENTITY="##########" security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" -D "$CERT_IDENTITY" -t private "$KEYCHAIN_PATH" - echo $(security find-identity) The echo at the end returns the following: Policy: X.509 Basic Matching identities 0 identities found Valid identities only 0 valid identities found Running the same command via ssh/terminal over VNC after the build fails returns the following: Policy: X.509 Basic Matching identities 1) C6......A2 "iPhone Distribution: ###########" 1 identities found Valid identities only 1) C6......A2 "iPhone Distribution: ###########" 1 valid identities found Which suggests that the keychain creation and certificate import is working as expected. I'm not ruling out the possibility of this being an issue on gitlab's end, but this has been working historically, and only really stopped working since we've updated to Sonoma (we're on 14.7.1 now). We have an active runner on Ventura 13.6.1 that's working still.
4
0
509
Dec ’24
PKCS#12
Hi all, I’m trying to find a documentation about the supported encryption algorithms for p12 files to be imported in iOS. I can see in iOS 18 changelog that AES-256-CBC is now supported, but cannot find a detailed view on which list of algorithms are supported. Would appreciate it if you could point me in the right direction! Thanks in advance
5
0
691
Dec ’24
SSL issue for specific user
Hi Team We are facing a problem in our app for one particular user the url session is giving below error. Rest for all the users its working fine. Below is the complete error we get from user device. {"type":"video_player","error":"Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://api.vimeo.com/videos/1020892798, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<4>, _NSURLErrorRelatedURLSessionTaskErrorKey=(\n "LocalDataTask .<4>"\n), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://api.vimeo.com/videos/1020892798, NSUnderlyingError=0x301ea8930 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9836, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9836, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: pdp_ip0, ipv6, dns, expensive, uses cell}}, _kCFStreamErrorCodeKey=-9836}"} Device info device_type iOS device_os_version 18.1.1 device_model iPhone 11 Please let me know how we can resolve for one particular user. Or what we can adivse.
1
0
599
Dec ’24
How to integrate keychain in the authorization plugin
Hello, I'm currently working on an authorization plugin for macOS. I have a custom UI implemented using SFAuthorizationPluginView (NameAndPassword), which prompts the user to input their password. The plugin is running in non-privileged mode, and I want to store the password securely in the system keychain. However, I came across this article that states the system keychain can only be accessed in privileged mode. At the same time, I read that custom UIs, like mine, cannot be displayed in privileged mode. This presents a dilemma: In non-privileged mode: I can show my custom UI but can't access the system keychain. In privileged mode: I can access the system keychain but can't display my custom UI. Is there any workaround to achieve both? Can I securely store the password in the system keychain while still using my custom UI, or am I missing something here? Any advice or suggestions are highly appreciated! Thanks in advance!
1
0
571
Dec ’24
How to Use System Keychain for Password Storage in an Authorization Plugin with Custom UI?
Hello developers, I'm currently working on an authorization plugin for macOS. I have a custom UI implemented using SFAuthorizationPluginView, which prompts the user to input their password. The plugin is running in non-privileged mode, and I want to store the password securely in the system keychain. However, I came across an article that states the system keychain can only be accessed in privileged mode. At the same time, I read that custom UIs, like mine, cannot be displayed in privileged mode. This presents a dilemma: In non-privileged mode: I can show my custom UI but can't access the system keychain. In privileged mode: I can access the system keychain but can't display my custom UI. Is there any workaround to achieve both? Can I securely store the password in the system keychain while still using my custom UI, or am I missing something here? Any advice or suggestions are highly appreciated! Thanks in advance! 😊
1
0
635
Dec ’24
Secure Enclave Key Persistence When Passcode is Removed
I am using the Secure Enclave to generate private keys with kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly and SecAccessControlCreateFlags.biometryCurrentSet. The public key is derived from the Secure Enclave private key at creation and stored in the Keychain for later retrieval. During testing, I observed the following: When the device's passcode is removed, the public key stored in the Keychain is deleted as expected. However, the private key in the Secure Enclave can still be fetched using SecItemCopyMatching, despite being tied to the passcode for protection. My questions are: Is this behavior expected? How does the Secure Enclave manage private keys in scenarios where the passcode is removed? Is there a way to ensure that the Secure Enclave private key is deleted entirely (not just rendered inaccessible) when the passcode is removed? Any clarification or relevant documentation references would be very helpful. Thank you!
2
1
569
Dec ’24
Write Permissions Error While Storing Password in System Keychain Using Authorization Plugin
I'm developing an authorization plugin for macOS and encountering a problem while trying to store a password in the system keychain (file-based keychain). The error message I'm receiving is: Failed to add password: Write permissions error. Operation status: -61 Here’s the code snippet I’m using: import Foundation import Security @objc class KeychainHelper: NSObject { @objc static func systemKeychain() -> SecKeychain? { var searchListQ: CFArray? = nil let err = SecKeychainCopyDomainSearchList(.system, &searchListQ) guard err == errSecSuccess else { return nil } let searchList = searchListQ! as! [SecKeychain] return searchList.first } @objc static func storePasswordInSpecificKeychain(service: String, account: String, password: String) -> OSStatus { guard let systemKeychainRef = systemKeychain() else { print("Error: Could not get a reference to the system keychain.") return errSecNoSuchKeychain } guard let passwordData = password.data(using: .utf8) else { print("Failed to convert password to data.") return errSecParam } let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecValueData as String: passwordData, kSecUseKeychain as String: systemKeychainRef // Specify the System Keychain ] let status = SecItemAdd(query as CFDictionary, nil) if status == errSecSuccess { print("Password successfully added to the System Keychain.") } else if status == errSecDuplicateItem { print("Item already exists. Consider updating it instead.") } else { print("Failed to add password: \(SecCopyErrorMessageString(status, nil) ?? "Unknown error" as CFString)") } return status } } I am callling storePasswordInSpecificKeychain through the objective-c code. I also used privileged in the authorizationDb (system.login.console). Are there specific permissions that need to be granted for an authorization plugin to modify the system keychain?
1
0
635
Dec ’24
[MacOS] Determining whether user already has passkey for given domain
Hi, I'm leveraging ASAuthorizationSecurityKeyPublicKeyCredentialProvider to authenticate users to an internal service using security keys or passkeys. I'm not using Sign in with Apple - registration is done in another internal service. We're using associated domains. This is on MacOS only. I'm wondering whether I can programatically determine whether the user has a passkey enrolled with our super-secret-internal-service.com domain already? The reason I'm asking is simply better UX - if the user doesn't have a passkey enrolled, I'd like to avoid offering them an option to use a platform authenticator and only offer them to tap their security key. We can assume that all users already have their security keys enrolled already. So something like the following: let securityKeyProvider = ASAuthorizationSecurityKeyPublicKeyCredentialProvider(relyingPartyIdentifier: options.rpId) let securityKeyRequest = securityKeyProvider.createCredentialAssertionRequest(challenge: options.challenge.data(using: .utf8) ?? Data()) let platformProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: options.rpId) let platformKeyRequest = platformProvider.createCredentialAssertionRequest(challenge: options.challenge.data(using: .utf8) ?? Data()) var authRequests: [ASAuthorizationRequest] = [securityKeyRequest] if (userHasPasskeyForDomain("super-secret-internal-service.com")) { // TODO how do I check this?? authRequests.append(platformKeyRequest) } let authController = ASAuthorizationController(authorizationRequests: [platformKeyRequest, securityKeyRequest]) Many thanks!
1
1
580
Dec ’24
Swift AES CBC 256 Encryption With Static 32bit Key and 32bit IV
We have the below Implementation in Android and the same has to be integrated into Swift. Key :- "d95acd54b4a821ff32c52825q931c194" IV :- "687b9509c25a34b8ad076346s8353d67" Here Both the Key and IV are 32 bits and below is the android code. public class AESEncryption { private static final String key = "d95acd54c6a821ff32c52825b931c194"; private static final String initVector = "687b9509c25a14b8ad076346d8353d67"; static byte[] bte = hexToBytes(initVector); public static String encrypt(String strToEncrypt) { try { CommonCode.showLog("log", bte.toString()); IvParameterSpec iv = new IvParameterSpec(bte); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); CommonCode.showLog("IV after logs", iv.toString()); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] encrypted = cipher.doFinal(strToEncrypt.getBytes()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return Base64.getEncoder().encodeToString(encrypted).trim(); } else { return android.util.Base64.encodeToString(encrypted, android.util.Base64.DEFAULT).trim(); } } catch (Exception e) { CommonCode.showLog("Error while encrypting: ", e.toString()); } return null; } public static String decrypt(String strToDecrypt) { try { IvParameterSpec iv = new IvParameterSpec(bte); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))); } else { return new String(cipher.doFinal(android.util.Base64.decode(strToDecrypt, android.util.Base64.DEFAULT))); } } catch (Exception e) { CommonCode.showLog("Error while decrypting: " , e.toString()); } return null; } } How can we mimic the above in Swift? Here in Android they are using static byte[] bte = hexToBytes(initVector); to convert the 32bit IV into 16 bit Bytes Array I Have Tried the same approach on Swift below are the code snippet [Contents.swift](https://developer.apple.com/forums/content/attachment/60fab4f2-1496-4003-9f37-c195de95e94a)
9
0
10k
Dec ’24
exit(0)
In terms of the review/approval process, is it ok to use exit(0), under the following circumstance? An alert dialog pops up explaining that the app cannot be used on rooted or jailbroken devices. There is a button labeled "Exit App" Or should I just let the app sit there doing nothing on the splash screen?
1
0
580
Nov ’24
Storing Password in System keychain (File-Based Keychain) for MFA Authorization Plugin
Hi everyone, I’m currently developing an MFA authorization plugin for macOS and am looking to implement a passwordless feature. The goal is to store the user's password securely when they log into the system through the authorization plugin. However, I’m facing an issue with using the system's login keychain (Data Protection Keychain), as it runs in the user context, which isn’t suitable for my case. Therefore, I need to store the password in a file-based keychain instead. Does anyone have experience or code snippets for objective-c for securely storing passwords in a file-based keychain (outside of the login keychain) on macOS? Specifically, I'm looking for a solution that would work within the context of a system-level authorization plugin. Any advice or sample code would be greatly appreciated! Thanks in advance!
3
0
552
Nov ’24
macOS Authorization Plugin: Keychain Error -25308 When Storing Password
Hi everyone, I'm working on a macOS authorization plugin (NameAndPassword) to enable users to log into their system using only MFA, effectively making it passwordless. To achieve this, I'm attempting to store the user's password securely in the Keychain so it can be used when necessary without user input. However, when I attempt to store the password, I encounter error code -25308. Below is the code I'm using to save the password to the Keychain: objc code (void)storePasswordInKeychain:(NSString *)password forAccount:(NSString *)accountName { NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: @"com.miniOrange.nameandpassword", (__bridge id)kSecAttrAccount: accountName, (__bridge id)kSecValueData: passwordData, (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleAfterFirstUnlock }; // Delete any existing password for the account OSStatus deleteStatus = SecItemDelete((__bridge CFDictionaryRef)query); if (deleteStatus == errSecSuccess || deleteStatus == errSecItemNotFound) { [Logger debug:@"Old password entry deleted or not found."]; } else { [Logger error:@"Failed to delete existing password: %d", (int)deleteStatus]; } // Add the new password OSStatus addStatus = SecItemAdd((__bridge CFDictionaryRef)query, NULL); if (addStatus == errSecSuccess) { [Logger debug:@"Password successfully saved to the Keychain."]; } else { [Logger error:@"Failed to save password: %d", (int)addStatus]; } } Any insights or suggestions would be greatly appreciated!
3
0
805
Nov ’24
WKWebView Challenges while authenticating PIV Certificates
Hi, I have a SAML authentication scenario with MFA(probably Okta) in my app that runs in WKWebView using Cordova. I am currently doing POC to authenticate PIV certificates(either one of the 3 Issuers: DISA Purebred, Intercede and Entrust) in WKWebView with Cordova. As if now, I have found that WKNavigationDelegate method: didReceive challenge, we can authenticate the certificate. Also, these PIV certificates which are stored in the form of .p12 in Apple's keychain group needs to be imported using function: SecPKCS12Import. Please let me know if my understanding is correct or if there are any implementation challenges in WKWebView with Cordova. I would highly appreciate if any information regarding this can be provided.
5
0
565
Nov ’24
iCloud Private Relay on local network (LAN)
Hi, I need a version of a web app to be accessible on a local network (LAN), when the users connect to a wifi without internet access. I provide a valid TLS certificate to validate the website. There is also a local DNS (dnsmasq), with the following entries to return NXDOMAIN, as specified by the documentation. server=/mask.icloud.com/ server=/mask-h2.icloud.com/ However, without internet (no cellular data), there is an error in Safari instead of the website. When there is some internet connection, there is a warning that allows to continue to the website by showing the IP address, which is not clear for the user. iPhone users are very frustrated. Is there a solution?
0
0
448
Nov ’24
When performing device certificate authentication on iOS18, it takes time to respond.
We are using device certificates for authentication when logging into our web page. After updating an iPhone 12 to iOS 18, the authentication process takes up to two minutes to respond. Upon investigating IIS, it was found that the certificate is not being presented from the iPhone, resulting in a timeout. This issue is affecting our operations, and we need a solution urgently. Could you please advise on how to resolve this?
2
1
549
Nov ’24