对于我的项目,我很感兴趣使用 webauthn (FaceID TouchID) 来确保安全。在 Google 和 Github 上挖掘之后,我可以构建简单的 webauthn。但是,由于缺乏 javascript 和身份验证技术,我不明白为什么这段代码可以在 Mac(计算机)上运行良好,但不能在 Safari iOS(iPhone)上运行。
这里的代码:
<script>
function printHex(msg, buf) {
if (ArrayBuffer.isView(buf) && buf.buffer instanceof ArrayBuffer) {
buf = buf.buffer;
}
var response = '';
if ((typeof msg != "string") ||
(typeof buf != "object")) {
return "Bad args to printHex";
}
if (!(buf instanceof ArrayBuffer)) {
return "Attempted printHex with non-ArrayBuffer:", buf;
}
var arr = new Uint8Array(buf);
var len = buf.byteLength;
var i;
var str = "";
response += msg, `(${buf.byteLength} bytes)`;
for (i = 0; i < len; i++) {
var hexch = arr[i].toString(16);
hexch = (hexch.length == 1) ? ("0" + hexch) : hexch;
str += hexch.toUpperCase() + " ";
if (i && !((i + 1) % 16)) {
response += str;
str = "";
}
}
if ((i) % 16) {
response += str;
}
return response;
}
var createCredentialDefaultArgs = {
publicKey: {
rp: {
name: "Acme",
icon: "https://www.w3.org/StyleSheets/TR/2016/logos/W3C"
},
user: {
id: new Uint8Array(16),
name: "test@test.com",
displayName: "test"
},
pubKeyCredParams: [{
type: "public-key",
alg: -7,
transports: "internal",
}],
attestation: "direct",
timeout: 60000,
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,
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
]).buffer
}
};
var getCredentialDefaultArgs = {
publicKey: {
timeout: 60000,
// allowCredentials: [newCredential]
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,
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
]).buffer
},
};
((async function () {
var cred = await navigator.credentials.create(createCredentialDefaultArgs);
console.log("NEW CREDENTIAL", cred);
document.getElementById("rawId").innerHTML = printHex("rawId: ", cred.rawId);
document.getElementById("attestationObject").innerHTML = printHex("attestationObject: ", cred.response.attestationObject);
document.getElementById("clientDataJSON").innerHTML = printHex("clientDataJSON: ", cred.response.clientDataJSON);
var idList = [{
id: cred.rawId,
transports: ["internal"],
type: "public-key"
}];
getCredentialDefaultArgs.publicKey.allowCredentials = idList;
var assertion = await navigator.credentials.get(getCredentialDefaultArgs);
console.log("ASSERTION", assertion);
document.getElementById("assertion").innerHTML = assertion;
document.getElementById("clientDataJSON").innerHTML = printHex("clientDataJSON", assertion.response.clientDataJSON);
document.getElementById("authenticatorData").innerHTML = printHex("authenticatorData", assertion.response.authenticatorData);
document.getElementById("signature").innerHTML = printHex("signature", assertion.response.signature);
document.getElementById("userHandle").innerHTML = printHex("userHandle", assertion.response.userHandle);
})())
.then(() => console.log("done"))
.catch((err) => console.log("ERROR:", err));
</script>
<div id="rawId"></div>
<div id="attestationObject"></div>
<div id="clientDataJSON"></div>
<div id="assertion"></div>
<div id="clientDataJSON"></div>
<div id="authenticatorData"></div>
<div id="signature"></div>
<div id="userHandle"></div>