Open droider91 opened 1 year ago
Hi @droider91 , Here is the flow you need to follow to work with SKFS 1) Call the preregister API to get the challenge (Which you are already doing) 2) The application now uses the response from the fido server and makes the create credential call (which i believe you are doing as well) 3) You now need to call the Register API and register the new credential with the FIDO server. (I believe you may be missing this step).
4) Only when the fido server has successfully stored the new credential, you can call the preauthenticate challenge.
Let me know if you are making the register call before making any preauthenticate calls.
Thank you Pushkar
Hello @push2085
Thanks for your reply
As you said for point number 3, I was not calling the register api(as I am not aware of the flow)
Now After creating the public key credential
I called api with this request.
{ "username": "devendra", "clientUri": "fidoid.com", "authenticatorData": { "id": "", "rawId": "", "response": { "attestationObject": "", "clientDataJSON": "" }, "type": "public-key" } }
I am extracting these values from the PublicKeyCredential
And received the response success.
Now what is the next step?
Also I have one doubt is that the pub key cred I sent to server is without attested like I did not touch biometric.
So my doubt is When I will be asked to do the biometric check?
Hi @droider91 , Based on what kind of application you are creating you may have to call different API's to register a FIDO credential but regardless the steps will remain the same. 1) Call pre register API on SKFS to get challenge 2) Take the response from step 1 and call the FIDO2 API (platform dependent) to create credential 3) Call register API on SKFS to save the credential. After this 4) Call pre authenticate API on SKFS to get challenge 5) Take the response from step 4 and call the FIDO2 API (platform dependent) to get assertion. 6) Call the authenticate API on SKFS to verify assertion.
If you are creating a web application, take a look at one of our sample applications for javascript sample to make the FIDO calls (https://github.com/StrongKey/fido2/blob/master/sampleapps/java/basic/server/src/main/webapp/js/fido2demo.js)
If you are making a iOS application, you can look at our sample iOS app to look at how to make fido calls (https://github.com/StrongKey/fido2/tree/master/sampleapps/swift/StrongKeyFIDODemo)
If you are creating an android application, you can look at our sample SACL application for code snippets (https://github.com/StrongKey/fido2/tree/master/sampleapps/java/sacl/mobile/android) or go to android fido2 api (https://developers.google.com/identity/fido/android/native-apps).
In all of above when you make a make credential call, you have to pass in options, which will determine what kind of authenticator will be registered.
If your device supports biometrics and is enabled, it should prompt you for it.
Also do this for the next test, on the FIDO server, enable fine logging (in a terminal) shell> asadmin set-log-levels SKFS=FINE
Run a registration and capture logs for the specific transaction from /usr/local/strongkey/payara5/glassfish/domains/domain1/logs/server.log
Attach the log to this issue and I can look and let you know what kind of registration was processed.
Thank you Pushkar
Hello @push2085 As you directed above,
var preauthenticateChallenge = PreauthenticateChallenge() preauthenticateChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = authData.Response?.rpId challenge = authData.Response?.challenge allowCredentialsJSONArray = JSONArray(Gson().toJsonTree(authData.Response?.allowCredentials).toString()) allowCredentials = JSONArray( Gson().toJsonTree(authData.Response?.allowCredentials).toString() ).toString() }
And then created the authenticateSignature
sign = AuthenticatorGetAssertion.execute( ContextWrapper(context), preauthenticateChallenge, publicKeyCredential, 1, "https://fidoid.com" ) as AuthenticationSignature
and get Signature object from ` val fidoImpl = FidoAuthenticatorImpl(context)
val bioSignature = fidoImpl.getSignatureObject(
publicKeyCredential?.credentialId,
ContextWrapper(context)
) as Signature`
and passed this bioSignature to biometric prompt
and finally if biometric success
{"clientUri":"https://dev-sp42.compactidentityqa.com","publicKeyCredential":{"id":"eeyJrZXluYW1lIjoiM0RBM0U1MzcxNzEyMjg5MC1FMUFBQjZDNkI4OUM5QjFBLUQyODJEQTY5RUMzMkQxQ0YtODMzN0IyRTczRTk2NTE1MCIsIm9yaWdpbiI6IkdFTkVSQVRFRCIsImFsZ29yaXRobSI6IkVDIFtzZWNwMjU2cjFdIiwic2l6ZSI6MjU2LCJ1c2VyYXV0aCI6dHJ1ZSwic2Vtb2R1bGUiOiJ0cnVlIFtUUlVTVEVEX0VYRUNVVElPTl9FTlZJUk9OTUVOVF0iLCJwdWJsaWNrZXkiOiIzMDU5MzAxMzA2MDcyYTg2NDhjZTNkMDIwMTA2MDgyYTg2NDhjZTNkMDMwMTA3MDM0MjAwMDQ1NmRlYjcxNjhjOTkxNTAzNjE3MzNiNzIwNDE4ZGE1MTY2ODgxNDFjNGY4MjFkMWI3NzE3MTljZGI2OWQ5MGVhYzk3ZDJlNGJkZWM4MDI3NGE0ZDc1NDVlMTkyMmJhMmNlYzc1NjYwYmEyZTFkZjIxYWU4NDRjZDU5ZDhhODFlMCJ9","rawId":"eyJrZXluYW1lIjoiM0RBM0U1MzcxNzEyMjg5MC1FMUFBQjZDNkI4OUM5QjFBLUQyODJEQTY5RUMzMkQxQ0YtODMzN0IyRTczRTk2NTE1MCIsIm9yaWdpbiI6IkdFTkVSQVRFRCIsImFsZ29yaXRobSI6IkVDIFtzZWNwMjU2cjFdIiwic2l6ZSI6MjU2LCJ1c2VyYXV0aCI6dHJ1ZSwic2Vtb2R1bGUiOiJ0cnVlIFtUUlVTVEVEX0VYRUNVVElPTl9FTlZJUk9OTUVOVF0iLCJwdWJsaWNrZXkiOiIzMDU5MzAxMzA2MDcyYTg2NDhjZTNkMDIwMTA2MDgyYTg2NDhjZTNkMDMwMTA3MDM0MjAwMDQ1NmRlYjcxNjhjOTkxNTAzNjE3MzNiNzIwNDE4ZGE1MTY2ODgxNDFjNGY4MjFkMWI3NzE3MTljZGI2OWQ5MGVhYzk3ZDJlNGJkZWM4MDI3NGE0ZDc1NDVlMTkyMmJhMmNlYzc1NjYwYmEyZTFkZjIxYWU4NDRjZDU5ZDhhODFlMCJ9","response":{"authenticatorData":"30aa545e970026ca59b4d0ed9f1c185c577c10074891316b19aab7e900404905dc400000001cafebabecafebeef0123456789abcdef0043334441334535333731373132323839302d453141414236433642383943394231412d443238324441363945433332443143462d38333337423245373345393635313530a501020326200121582056deb7168c99150361733b720418da516688141c4f821d1b771719cdb69d90ea225820c97d2e4bdec80274a4d7545e1922ba2cec75660ba2e1df21ae844cd59d8a81e0a16375766d8183040601","clientDataJSON":"eeyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiMU5KMWlCX0kwRC11ZWdDLXBWMll0USIsIm9yaWdpbiI6Imh0dHBzOlwvXC9kZXYtc3A0Mi5jb21wYWN0aWRlbnRpdHlxYS5jb20iLCJ0b2tlbkJpbmRpbmciOnsic3RhdHVzIjoibm90LXN1cHBvcnRlZCJ9fQ","signature":"MEUCIQCOISSwxKDfDReMgYXZ589W8UOqG8gNWUC-U6T1t240rwIgMfEBJmgf_xC2nqvndcI8EHg9aHNSkDdMvLha0QTUn14","userHandle":""},"type":"public-key"},"username":"devendra"}
Is this correct process?
Hi @droider91, Theoretically it is the right process but you should verify with the server and see if it succeds or fails and paste errors here if you cannot figure out the problem
Thank you Pushkar
Hello @push2085 Thank you for your support But I want to develop same app with iOS, In that case would you please elaborate the flow theoretically for iOS, not complete code but classes name with uses.
Hi @droider91, The flow remains the same regardless of the platform and the only variable is how to call the WebAuthn API on each platform. On web you make the JavaScript calls. On Android you can call the Android fido2 API. On iOS/macOS Apple has their Public-Private Key Authentication APIs which support both Passkeys and Security Keys. You can take a look at our iOS Demo Application on how we used Apple's API with SKFS to support Passkeys and Security Keys in a Native iOS application.
Thanks, Abhishek
First of all thanks for the awesome future ready feature @push2085 @arshadnoor Here is what I am doint in my android application.
{"Response":{"rp":{"name":"FIDOServer","id":"fidoidqa.com"},"user":{"name":"devendra","id":"s5wXaholuoVwk86KQ0d_hmIxOkQPNS-bBBes8X4Cex8","displayName":"devendraLiapC"},"challenge":"COJ03Ch_6KDjlvnZ1jg_Qw","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-8},{"type":"public-key","alg":-47},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-38}],"excludeCredentials":[{"type":"public-key","id":"NEVDOUQzNkMzMDBEM0U3MS1FNDczNTQ3QUVDRDQ1ODRELTk1MEJFOTM2NTI5MEIxNjctMTIxNkNFQjY1ODIzQTI5OQ","alg":-7},{"type":"public-key","id":"MUUzMDY0RkNGQUZEOTM5Ni1FMzlFOUM2MkUwOTQ4NzcwLTA0NzUyMEFBREM0ODUwM0UtMEU4ODdFOEFCRjFCMDE3QQ","alg":-7},{"type":"public-key","id":"hhkXnYmUiu_bzLy5HPHJvZs6TQA-302jRdeLHBgpL40","alg":-257}],"attestation":"direct"}}
PreregisterChallenge
var preregisterChallenge = PreregisterChallenge() val authenticatorSelectionCriteria = AuthenticatorSelectionCriteria() authenticatorSelectionCriteria.authenticatorAttachment = "Android" authenticatorSelectionCriteria.isRequireResidentKey = true authenticatorSelectionCriteria.userVerification = "required" val authSelectionJson = Gson().toJson(authenticatorSelectionCriteria) val myCustomArray: JsonArray = Gson().toJsonTree(userData.Response?.pubKeyCredParams).asJsonArray preregisterChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = userData.Response?.rp?.id userid = "1001" username = "devendra" displayName = "devendra" challenge = userData.Response?.challenge authenticatorSelectionJSONObject = JSONObject(authSelectionJson) authenticatorSelection = authSelectionJson publicKeyCredentialParams = myCustomArray.toString() credParamsJSONArray = JSONArray(myCustomArray.toString()) }
and passing this challenge like thisval publicKeyCredential = AuthenticatorMakeCredential.execute( ContextWrapper(context), preregisterChallenge, "fidoidqa.com" ) as PublicKeyCredential
I am getting thepublickKeyCredential
without any error then I am creating preauth challengevar preauthenticateChallenge = PreauthenticateChallenge() preauthenticateChallenge.apply { id = 100 uid = 1001 did = 1003 rpid = userData.Response?.rp?.id challenge = userData.Response?.challenge } // Generate the digital signature val sign = AuthenticatorGetAssertion.execute( ContextWrapper(context), preauthenticateChallenge, publicKeyCredential, 1, "fidoidqa.com" )
But in this process I am not getting the biometric prompt to sign the public key.Here is what I want to do
Please let me know where I am doing wrong in code or what is the process to do the above points Thanks again