Post not yet marked as solved
WebKit PR #9891 added support for the WebAuthn Large Blob extension in the browser. (Hooray!) Does Apple plan to add support for this extension (or similar, such as PRF) in MacOS and iOS platform authenticators? If so, where can we track this?
More context: I've been developing with these extensions using other authenticators. After #9891 I hoped my native platform authenticator on Macbook Pro M1 (with Safari Preview Release 170 on Ventura 13.4) might support largeBlob. But after testing it seems I was mistaken.
Thanks!
Post not yet marked as solved
Hi, I am facing an issue with timeout implementation on navigator.credentials.create().
Trying to build an authentication using webauthn. I am doing navigator.credentials.create() upon user specific action(button-click) which then prompts dialog for user to perform biometric gesture.
I am passing timeout value in publickey credential request. However noticed that timeout value is not honored on Safari and dialog which is shown to user for biometric gesture stays forever.
below is how I am passing timeout
"challenge": "testchanllengevalue",
"rp": { "name": "test.com" },
"user": {
"id": "12345-543212-12345-54321",
"name": "NAME",
"displayName": "NAME"
},
"attestation": "direct",
"timeout": 20000,
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"requireResidentKey": false,
"userVerification": "required"
},
"pubKeyCredParams": [
{ "type": "public-key", "alg": -7 },
{ "type": "public-key", "alg": -257 }
]
}
Anyone faced this issue and is there any know workaround for this ?
Thanks!
Hi,
I'd like to allow only a specific process to read sensitive items from keychain (based on process signature using method SecItemCopyMatching), and fail any other read attempt.
Is it possible, what are the access control rules I can define for keychain access if this is not possible ?
I'm now using the default user keychain, perhaps I should create a different keychain with non-trivial access control, so that not all processes that are running with user context or even with root privileges, would be able to get the data.
Thanks
Here's my read example :
func read(service: String, account: String) -> Data? {
let query = [
kSecAttrService: service,
kSecAttrAccount: account,
kSecClass: kSecClassGenericPassword,
kSecReturnData: true
] as CFDictionary
var result: AnyObject?
SecItemCopyMatching(query, &result)
return (result as? Data)
}
Post not yet marked as solved
Hi there, we are currently playing around with passkeys and especially with the client side discoverable credentials flow as we don't require any email (or account id) from our users.
Our current authentication flow:
request challenge from server
sign challenge with existing passkey
send signed challenge to server
server returns auth result and OAuth token to authenticate further requests.
Our registration flow in case no passkey exists:
request credential registration options from server (includes a UUID which is used to create the passkey as we don't require email/user name from the user
create passkey locally
upload public key to server
After the registration has completed the authentication process will be retried.
Let's look at following example:
The user has successfully created a passkey for our platform and is able to authenticate against the server. All good so far. For some arbitrary reason the public key on the server gets deleted (possibly by deleting the account, or other reasons). The next time the user tries to authenticate against the platform the authentication is rejected, which is correct. The logical next step would be to register a new passkey. But there is the catch. By registering a new key a new UUID will be requested from the server which will create a new passkey. As we are using the client side discoverable credentials we don't know the user id with which the passkey has been created. The next time the user tries to authenticate he will be prompted with the action sheet to select one of the two existing keys.
I would like to know whether there is a way to re-register an existing passkey in order to prevent the key selection step.
Additionally, is there any way to customize (use a different userId) the passkey action sheet message?
"Do you want to sign in with you saved passkey for '4636bbbf-27fa-4a54-b892-a2aec8b0d68e'?" doesn't help the user a lot, especially when there are multiple keys existing.
Thanks for your support!
Post not yet marked as solved
I am using AWS Cloud Services, when I create an EC2 instance Amazon automatically generates a Security Certificate in .pem file extension, it downloads to my computer, when I click it or try and import it to Keychain, there is an error. Terminal commands cannot locate the file. I used Homebrew to try and convert the file to .12, that will not work given the file cannot be located.
Any thoughts?
Post not yet marked as solved
I find myself in the keychain a series of accounts and related pw, normally created at the time, transformed into very long character strings like MEIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAw****************
The particular feature is that account and relative pw are almost the same, just one character varies (I think) but they are not, of course, the ones I chose. And, just as obviously, they don't work when requested by the sites...
The phenomenon is recent, although I remember noticing something like this looking at the pw in my Mac keychains several macOSs ago - I then thought of some form of coding. But seeing these very long strings being proposed automatically when requested by the site, instead of original accounts and pw, worries me ... does anyone have experience of such a thing?
Post not yet marked as solved
After I upgrade my iPhone from iOS 16.3 to 16.4, my passkey apps stopped working, including the Shiny app.
I only updated the domain and web credentials entitlement from example.com to my domain name, nothing else, and Shiny was working fine on iOS 16.3.
After the update, the app is unresponsive when tapping the "sign in" or "Create Account" buttons. In the logs, I see:
2023-04-08 20:35:26.380433+0200 Shiny[843:46331] [Authorization] ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1001 "(null)"
2023-04-08 20:35:26.425071+0200 Shiny[843:46331] Request canceled.
The AASA file also didn't change, and lists the correct domain.
$ curl https://rp.example.com/.well-known/apple-app-site-association
{
"webcredentials": {
"apps": [
"UVWXYZ1234.com.example.apple-samplecode.ShinyUVWXYZ1234"
]
}
}
where UVWXYZ1234 stands for my TEAMID and is also used as disambiguator.
Another app is also no longer working, but instead shows this log message:
2023-04-08 20:48:23.841219+0200 AppName[958:52549] [Authorization] ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
2023-04-08 20:48:23.845169+0200 AppName[958:52549] ASAuthorization Error: ["NSLocalizedFailureReason": Application with identifier UVWXYZ1234.com.example.app is not associated with domain rp.example.com]
where rp.example.com is my domain name and UVWXYZ1234.com.example.app stands for my app's bundle ID.
Both log messages were absent when still running iOS 16.3
Has anything changed in iOS 16.4 that requires an update to these apps?
See also FB12105522.
Post not yet marked as solved
Hello Team,
Am dealing with this weird issue implementing passkeys login for our website in iPad and iPhone devices
1) Auto fill use case (iPad safari browser (16.3.1) - this works)
a. User successfully registered for passkeys
b. Navigates to the login screen
c. On Page load, the mediational – credential get requests is initiated
d. User selects the passkey autofill and everything works as expected
2) Non auto fill usecase (iPad safari browser (16.3.1) this doesn't work)
a. User successfully registered for passkeys
b. Navigates to the login screen
c. On Page load, the mediational – credential get requests is initiated
d. User bypasses the autofill option prompted, **and manually types in the email and clicks on submit**
e. Abort controller’s abort signal sent to the mediational get request initially fired
f. A new credential.get request is created and brings up the authenticator pop up but also throws am NotAlloweErr in the background.
(Appears the second promise is also rejected in the ios devices.)
See the same behavior in webauthn.io website.
Post not yet marked as solved
Hey!
Is it possible to test passkeys against a locally running server in simulator with self-signed certificate? As far as I can tell, the certificate is trusted on the Simulator and Safari has no trouble communicating with the server or fetching the apple-app-site-association file.
The error I'm getting is
ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
Error: ["NSLocalizedFailureReason": Application with identifier FAKETEAMID.com.example.apple-samplecode.Shiny is not associated with domain webauthn-api.local]
When running the Shiny example app. There is an apple-app-site-association available in https://webauthn-api.local:7001/.well-known/apple-app-site-association:
{
"webcredentials": {
"apps": [ "FAKETEAMID.com.example.apple-samplecode.Shiny" ]
}
}
And in the Associated Domains, I've added:
webcredentials:webauthn-api.local:7001?mode=developer
I saw here https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains that to use a local server with the apple-app-site-association, one should add ?mode=developer to the entitlement.
However, looking at the logs for the server, the simulator does not seem to ever attempt fetching /.well-known/apple-app-site-association file, so the developer mode does not seem to have any effect. Is the developer mode supposed to work with webcredentials service. Documentation linked above doesn't make any exclusions for that.
Post not yet marked as solved
When I use Keychain Access to access .pem files, I receive an error, "An error has occurred. Unable to import an item. The contents of this item cannot be retrieved". I have used every method suggested such as change access the open only function. This it is not an available option to me. I have cleared all keys/certificates and rebooted my computer an innumerable amount of times. Utilized various method under "import items," saved to system, system roots, and local items and nothing works.
The solution seems to involve removing and reinstalling the app, however, I am not able to perform this action. No matter the method used to access this app, via spotlight, go app, go utilities, or app search using finder, there is no option to delete the app. When I drag it to trash, it bounces back. I have two plus one guest users. I have repeated each of these actions under each user login believing one could be a master account.
I ran the following command code to remove the app: sudo rm -rf / Applications/Utilities/Keychain\Access.app. After prompting me for my password, which seemed like a good sign, I receive the following message: rm: "/" may not be removed.
I am crippled in AWS because I am unable to decrypt and access Key Pairs.
I do not understand why I cannot delete the app. I do not understand why "keychain" may not be removed. Does anyone have any suggestions, thoughts, ideas, or considerations? I am grateful for any advice.
Post not yet marked as solved
Hello all,
I have a standard sign up form on my iOS app with the typical username and password fields. I'm using SwiftUI and have marked my TextField with the correct .textContentType.
TextField("Username", text: $username)
.padding()
.background(Color(.systemGray6))
.cornerRadius(8)
.padding(.bottom, 10)
.textContentType(.username)
I created this function inside the same swift file that I use to handle my registrations and signins.
func fetchChallenge(completion: @escaping (Data?) -> Void) {
let url = URL(string: "https://www.myurl.com/api/generate_challenge.php")!
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data, error == nil {
completion(data)
} else {
completion(nil)
}
}.resume()
}
This is what this server file looks like.
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
function generate_challenge() {
$randomBytes = openssl_random_pseudo_bytes(32);
return base64_encode($randomBytes);
}
$challenge = generate_challenge();
$response = array("challenge" => $challenge);
echo json_encode($response);
?>
My first question would be, is this what the new PassKey is expecting as a challenge? It says it should be unique each time, so I'm assuming that it doesn't need to be saved to the database. Is that correct? Or would this be considered to be the public key?
Next, how can I use the examply Shiny PassKey code in SwiftUI to call my functions and use passkeys and keychain? e.g. My custom functions....
func signInWithV1(username: String, password: String)
func signUpWithV1(userName: String, password: String)
My server is a linux server running nginx. I just can't seem to find anything on how to properly do this on the server side. I'm not sure what to save to the database and how you would integrate the above functions into the authorizationController and how to properly verifiy the let variables in the example code that I found from the Shiny Project.
If anyone has time to explain this I would be extrememly grateful! I'm assuming that I can't just use the Shiny code as is since it says that I need to Verify stuff inside the authorizationController. As of right now, my app simply saves the username and password to my database and I do checks to ensure the username and password is how I want it on the server side and the same when they login. However, nothing is saved to the keychain or passkey as of right now.
Thanks in advance to anyone who takes the time to explain this in detail! I would be very grateful!!
Hello all,
First post in the forums! I hope this question has not been answered already and I missed it. If it has, I apologize in advance.
I downloaded the Shiny demo code. I updated the AccountManager to use my domain. I placed the required file on my server in the .well-known folder. Here is my code. Note: I replaced example with my real domain.
{
"applinks": {
"details": [
{
"appIDs": [ "CC8JC8QC9K.com.example.Shiny" ],
}
]
},
"webcredentials": {
"apps": [ "CC8JC8QC9K.com.example.Shiny" ]
}
}
One thing I'm not clear on is what applinks are and if it is even needed for this service or not. In either case, I went ahead and included it.
I added webcredentials:example.com to the Associated domains section under Signing Capabilities for my target. Again, example is replaced with my domain. I also included applinks:example.com since I don't fully understand the importance of that just yet.
I have enabled Associated Domain for the app in my developer account and imported the AuthenticationServices framework into the project.
When I run the app I get the following errors.
2023-03-30 15:57:43.005597-0500 Shiny[64202:1563051] [Authorization] ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1001 "(null)"
2023-03-30 15:57:43.007370-0500 Shiny[64202:1562730] Request canceled.
I also noticed this in the sample code.
// Fetch the challenge from the server. The challenge needs to be unique for each request.
let challenge = Data()
Am I supposed to be doing something on my server? If so, where? I'm just not grasping why an Apple service such as this even relies on the developer's server to begin with.
A couple of final things to mention just in case it is relevant.
I have a wildcard domain.
My site uses a www redirect.
I do use https://
What am I missing? Any help would be greatly appreciated!
ios 16.4 passkey can't find passkey info
The passkey function was normal before ios 16.3, and the passkey information cannot be displayed after upgrading to 16.4
code :
let publicKeyCredentialProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: "xxxxx")
let passkyerequest = publicKeyCredentialProvider.createCredentialAssertionRequest(challenge: parameters.challenge)
let passkeysAllowCredentials = parameters.allowCredentials?.compactMap { credentialId -> ASAuthorizationPlatformPublicKeyCredentialDescriptor? in
let base64 = Base64.base64URLToBase64(base64URL: credentialId)
guard let credentialIdData = Data(base64Encoded: base64) else {
return nil
}
return ASAuthorizationPlatformPublicKeyCredentialDescriptor(credentialID: credentialIdData)
}
if let ids = passkeysAllowCredentials {
passkyerequest.allowedCredentials = ids
}
Coworkers are trying it and it's not working -- the google response says there was a problem with it, and not much else.
I do not have a yubikey (at least not yet 😄), and I'm really not good at the GUI stuff so I don't know as much about it as I probably should. Searching the fora here found a question and comment that didn't make a lot of sense to me, but again I admit to a lot of ignorance here.
So any pointers to where I should be look would be appreciated.
Post not yet marked as solved
I've watched a video about Meet passkeys and I have a question.
After key agreement have happened, the two devices connect to a relay server picked by the phone.
I understand that the key agreement local part uses Bluetooth.
After then, the FIDO CTAP operation does not use Bluetooth?
Does it uses Transmission Control Protocol?
What happens if I turn off Bluetooth, after the key agreement is finished?
Can you explain in more detail how FIDO CTAP operates and how client and authenticator exchange information after two devices connect to a relay server?
Post not yet marked as solved
Hi,
I referred to the documentation for reset passkeys - https://developer.apple.com/documentation/authenticationservices/public-private_key_authentication/supporting_passkeys#4047465 , this method createCredentialRegistrationRequest seems to be an instance of ASAuthorizationSecurityKeyPublicKeyCredentialRegistration and returns a registration request of the the type ASAuthorizationSecurityKeyPublicKeyCredentialRegistrationRequest, is this correct? When i tried to integrate the same, it gave "No algorithms specified for ASAuthorizationSecurityKeyPublicKeyCredentialRegistrationRequest" from iOS. So, i tried replacing the registration request with ASAuthorizationPlatformPublicKeyCredentialProvider with same params as expected for createCredentialRegistrationRequest with challenge, username and userId, but it ended up creating one more passkey which I could see in settings.
It created new passkey though I expected this to replace existing. is this expected?
Also, will this registration request expected to replace ALL passkeys created for this user for this domain or just 1 passkeys matching the user and domain?
Please let me know if I missed out anything. Thanks for your help
Post not yet marked as solved
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally a view controller <_SFAppAutoFillPasswordViewController: 0x106e22ee0> that is already being presented by <UIKeyboardHiddenViewController_Autofill: 0x106e25a10>.'
IOS16(not sure other OS version could reproduce this or not) click on textfield, then keyboard shows(with a key button above), click key button, it crashes randomly.
Post not yet marked as solved
Hello Apple,
We are developing Passkey FIDO login feature. It works fine in developer mode but in the production release, ASAuthorizationController returns error saying the "AppID is not associated with the domain". We verified the AASA file and it contains the AppID in webcredentials in the AASA file.
However, our AASA file content type is octet-stream instead of JSON. Our question is if this content-type is the root cause of the error?
Thank you,
Hi,
The Authenticator Attestation Global Unique Identifier (AAGUID) for Safari and also, from iOS App is zero’ed out, is this expected to stay this way, can this be considered an ideal differentiator between Passkeys from Apps in iOS/Safari from Mac and other webAuth N Credentials generated from other platform Authenticators as Chrome/Yubico and other vendors happen to send different values.
is this value expected to change in future?
Hi,
Is there a guideline from Apple to prevent re-enrollment from same RP and same user Id so that we dont create multiple passkeys for same user account, We have a use case within app to create Passkeys on successful Login, but currently there is no API[ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest] available to pass excludedCredentials for the user Id sent by RP[https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialcreationoptions-excludecredentials] so that iOS can avoid creating new Passkeys for same User Id and same RP.
If we end up creating multiple Passkeys for same RP and same User Id,basically RP has to maintain all Passkeys's publickey and credIds at their end, leading to authentication complexity.
Also,Due to re-enrollment for same user with same RP, this leads to authentication failures[as user might choose diff Passkey-CredId from Modal than the one for which Challenge is requested for] until RP supports truly discoverable credentials.
We could say to replace Passkeys during subsequent creation but it would invalidate passkeys already shared to others or in sync'ed devices on web[that might work based off of storedCredId] which would be already creating passkeys or adopt webAuthN on different browsers and create new credential there as well.
But, ASAuthorizationSecurityKeyPublicKeyCredentialRegistrationRequest has excludedCredentials though.