-
-
Save My1/6b6bb3d536d2b96cdfcabd60ca32c565 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<!-- | |
inspired by Mozilla Webauthn documentation: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API | |
copyright: 2019 Nicolas Mora <[email protected]> | |
license: MIT | |
--> | |
<title>Hmac-Secret webauthn Extension</title> | |
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/cbor.min.js"></script> | |
<!--<script type="text/javascript" src="cbor.js"></script>--> | |
</head> | |
<body> | |
<div> | |
Step 1: Create a new credential | |
</div> | |
<div> | |
<button type="button" id="create">New credential with Hmac-Secret extension</button> | |
</div> | |
<div id="createResult"> | |
</div> | |
<hr/> | |
<div> | |
Step 2: validate assertion | |
</div> | |
<div> | |
salt1 (required): <input type="text" id="salt1" value="0123456789ABCDEF" maxLength="16" placeholder="16 chars" /> | |
</div> | |
<div> | |
salt2 (optional): <input type="text" id="salt2" maxLength="16" placeholder="16 chars" /> | |
</div> | |
<div> | |
<button type="button" id="assert">Validate assertion with Hmac-Secret extension</button> | |
</div> | |
<div id="assertResult"> | |
</div> | |
</body> | |
</html> | |
<script type="text/javascript"> | |
var credentials = []; | |
function str2ab(str) { | |
var buf = new ArrayBuffer(str.length * 2); | |
var bufView = new Uint16Array(buf); | |
for (var i = 0, strLen = str.length; i < strLen; i++) { | |
bufView[i] = str.charCodeAt(i); | |
} | |
return buf; | |
} | |
function newCredential() { | |
var createCredentialDefaultArgs = { | |
publicKey: { | |
rp: { | |
name: "Acme" | |
}, | |
user: { | |
id: new Uint8Array(16), | |
name: "[email protected]", | |
displayName: "John P. Smith" | |
}, | |
pubKeyCredParams: [{ type: "public-key", alg: -7 }], | |
attestation: "direct", | |
timeout: 60000, | |
extensions: { | |
hmacCreateSecret: true | |
}, | |
challenge: new Uint8Array([ | |
0x8C, 0x0A, 0x26, 0xFF, 0x22, 0x91, 0xC1, 0xE9, 0xB9, 0x4E, 0x2E, 0x17, 0x1A, 0x98, 0x6A, 0x73, | |
0x71, 0x9D, 0x43, 0x48, 0xD5, 0xA7, 0x6A, 0x15, 0x7E, 0x38, 0x94, 0x52, 0x77, 0x97, 0x0F, 0xEF | |
]).buffer | |
} | |
}; | |
console.log("credential options", createCredentialDefaultArgs); | |
navigator.credentials.create(createCredentialDefaultArgs) | |
.then((cred) => { | |
console.log("credential", cred); | |
credentials.push({ | |
id: cred.rawId, | |
transports: ["usb", "nfc", "ble"], | |
type: "public-key" | |
}); | |
var attStmt = CBOR.decode(cred.response.attestationObject); | |
console.log("attStmt", attStmt); | |
if (attStmt.authData[32] & 0x80) { | |
document.getElementById("createResult").innerHTML = "extension flag set"; | |
} else { | |
document.getElementById("createResult").innerHTML = "extension flag not set"; | |
} | |
}) | |
.catch((err) => { | |
document.getElementById("createResult").innerHTML = "creation error"; | |
console.log("creation error", err); | |
}); | |
} | |
function newAssertion() { | |
var getCredentialDefaultArgs = { | |
publicKey: { | |
timeout: 60000, | |
allowCredentials: credentials, | |
challenge: new Uint8Array([ | |
0x79, 0x50, 0x68, 0x71, 0xDA, 0xEE, 0xEE, 0xB9, 0x94, 0xC3, 0xC2, 0x15, 0x67, 0x65, 0x26, 0x22, | |
0xE3, 0xF3, 0xAB, 0x3B, 0x78, 0x2E, 0xD5, 0x6F, 0x81, 0x26, 0xE2, 0xA6, 0x01, 0x7D, 0x74, 0x50 | |
]), | |
extensions: { | |
hmacGetSecret: { | |
salt1: str2ab(document.getElementById("salt1").value) | |
} | |
} | |
} | |
}; | |
if (document.getElementById("salt2").value) { | |
getCredentialDefaultArgs.publicKey.extensions.hmacGetSecret.salt2 = str2ab(document.getElementById("salt2").value); | |
} | |
console.log("assertion option", getCredentialDefaultArgs); | |
navigator.credentials.get(getCredentialDefaultArgs) | |
.then((assertion) => { | |
console.log("assertion", assertion); | |
if (assertion.response.authenticatorData[32] & 0x80) { | |
document.getElementById("assertResult").innerHTML = "extension flag set"; | |
} else { | |
document.getElementById("assertResult").innerHTML = "extension flag not set"; | |
} | |
}) | |
.catch((err) => { | |
document.getElementById("assertResult").innerHTML = "assertion error"; | |
console.log("assertion error", err); | |
}); | |
} | |
window.onload = function() { | |
document.getElementById("create").onclick = newCredential; | |
document.getElementById("assert").onclick = newAssertion; | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment