Skip to content

Instantly share code, notes, and snippets.

@Roadmaster
Created February 7, 2020 21:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roadmaster/8ad4016ff419ae8d3ec296a941c4935a to your computer and use it in GitHub Desktop.
Save Roadmaster/8ad4016ff419ae8d3ec296a941c4935a to your computer and use it in GitHub Desktop.
Webauthn demo/test in a single page.
<script type="text/javascript">
// Python to obtain the serverArgJson
/*
from webauthn import WebAuthnMakeCredentialOptions
chor = WebAuthnMakeCredentialOptions(
challenge="ar"*16,
rp_name="Ubuntu One SSO",
# VERY IMPORTANT: the RP_ID must MATCH the URL/HOSTNAME.
# Otherwise the browser will spit out Error creating
# credential: DOMException: "The operation is insecure." If you
# get this error and expand it, it'll tell you which host it
# was expecting.
rp_id="sso-xenial",
user_id="openid",
username="myusername",
display_name="my nice display name",
icon_url="",
attestation='indirect',
)
import json
print(json.dumps(chor.registration_dict))
*/
function b64stringToUint8Array(b64_string) {
return Uint8Array.from(atob(b64_string), c => c.charCodeAt(0));
}
// takes a uint8 array and returns a b64-encoded string representation of it.
// Maybe a function for this wasn't needed since it does one thing (tm) but it
// looks quirky and I feel better having it tested as a unit.
function Uint8ArrayToB64String(array) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(array)));
}
// takes a serverArgs as returned by the server (with b64-encoded payloads) and
// returns the expected payload object (with a publicKey property and
// Uint8Array payloads) to be fed into credentials.create.
function browserifyCredentialArgs(serverArgs) {
let { challenge, user } = serverArgs;
challenge = b64stringToUint8Array(challenge);
user.id = b64stringToUint8Array(user.id);
let credentialsForBrowser = Object.assign({}, serverArgs, {
challenge,
user
});
return { publicKey: credentialsForBrowser };
}
const doit = async(e) => {
e.preventDefault();
let serverArgJson = {
"challenge": "arararararararararararararararar",
"rp": {
"name": "Ubuntu One SSO",
"id": "sso-xenial"
},
"user": {
"id": "openid",
"name": "myusername",
"displayName": "my nice display name"
},
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -257,
"type": "public-key"
},
{
"alg": -37,
"type": "public-key"
}
],
"timeout": 60000,
"excludeCredentials": [],
"attestation": "indirect",
"extensions": {
"webauthn.loc": true
}
}
cargs = browserifyCredentialArgs(serverArgJson);
console.log(cargs);
try{
let regy = await navigator.credentials.create(cargs);
console.log(regy);
}
catch(err)
{
console.log("bummer", err);
}
}
document.addEventListener("DOMContentLoaded", e => {
document.querySelector('#register').addEventListener('click', doit);
});
</script>
<button id="register" type="submit">Register with WebAuthn</button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment