Last active
January 3, 2023 02:14
-
-
Save babelouest/9d865e69433a33d2e8a6f0a5ef9f9f1d to your computer and use it in GitHub Desktop.
might be usable in a foreseen future (this was written in 2019), but hmac-secret still isn't available in the browser I know of
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> |
Yes, hmac-secret
isn't implemented yet in any browser.
Understood, so currently there is still no way to encrypt data using WebAuthn?
Or is there any way to encrypt data using the platform hardware keys (e.g. using biometrics on MacOS / Windows)
Understood, so currently there is still no way to encrypt data using WebAuthn?
Actually no, but just to be accurate, hmac-secret
isn't per se an encryption algorithm, but a deterministic way to get a 32 or 64 bits number, using webauthn. This number can be used as an encryption key, but also as something else...
Or is there any way to encrypt data using the platform hardware keys (e.g. using biometrics on MacOS / Windows)
Not that I'm aware of, sorry...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ref back to chromium ticket
https://bugs.chromium.org/p/chromium/issues/detail?id=1023225