Skip to content

Instantly share code, notes, and snippets.

@mrnerdhair
Forked from babelouest/hmac-secret-demo.html
Last active August 18, 2021 23:30
Show Gist options
  • Save mrnerdhair/12eafda4cc647136a922a2e8209e9de8 to your computer and use it in GitHub Desktop.
Save mrnerdhair/12eafda4cc647136a922a2e8209e9de8 to your computer and use it in GitHub Desktop.
<!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 <nicolas@babelouest.org>
license: MIT
-->
<title>Hmac-Secret webauthn Extension</title>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cbor-js-unofficial@0.1.0-a4/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: "john.p.smith@example.com",
displayName: "John P. Smith"
},
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
extensions: {
hmacCreateSecret: true
},
challenge: new Uint8Array(32)
}
};
console.log("credential options", createCredentialDefaultArgs);
navigator.credentials.create(createCredentialDefaultArgs)
.then((cred) => {
console.log("credential", cred);
credentials.push({
id: cred.rawId,
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: {
allowCredentials: credentials,
challenge: new Uint8Array(32),
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