Register Credential & Sign/Verify
Register Credential
前后端数据传输: 对buffer进行编码传输
前端:
使用服务端 challenge 目的:防止binding时候有replay
Nodejs服务端:
创建challenge https://github.com/GoogleChromeLabs/passkeys-demo/blob/fa4db9d0fd08689a346fa0715fd47834fbd8870f/libs/auth.mjs#L217 验证challenge https://github.com/GoogleChromeLabs/passkeys-demo/blob/fa4db9d0fd08689a346fa0715fd47834fbd8870f/libs/auth.mjs#L265
不同语言SDK
java RegistrationValidationTest
AA sign
https://github.com/wevm/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/src/sign.ts#L46
https://github.com/wevm/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/src/credential.ts#L45 https://github.com/wevm/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/src/credential.ts#L139
AA Verify sign
两套方案:1. 链上验签, 2. 链下验签
因为 webAuthn 签名数据经过AA Account.sign两次encodeAbiParameters(
) 编码转化成链上合约可用的数据,所以验签有两种方式
链上:直接用编码后的数据调用合约(合约需要,看上去要加一个function)https://github.com/coinbase/smart-wallet/blob/facf1a5a00a393c859c77a7cff38de1e557c393f/src/CoinbaseSmartWallet.sol#L149 链下:将AA Account 签名的数据两次反decodeAbiParameters, 得到最初的webAuthn 签名数据,然后使用webauthn-p256 demo中相同的方式验签,需要提供publicKey https://github.com/841660202/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/playground/src/App.tsx#L182-L187
链上验签 vs 链下验签
链上验签优点:是一套逻辑代码,缺点:是需要加一个合约方法(或者可以使用webauthn-p256 代码中 的链上验证方案,只用合约bytecode https://github.com/wevm/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/playground/src/App.tsx#L134-L146)
链下验签优点:不用发请求 缺点:逆包装,两次decodeAbiParameters
其他参考
Credential encode
rawId encode 刚好是 Credential 的 id

const base64url = {
encode: function (buffer) {
const base64 = window.btoa(String.fromCharCode(...new Uint8Array(buffer)));
return base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
},
decode: function (base64url) {
const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
const binStr = window.atob(base64);
const bin = new Uint8Array(binStr.length);
for (let i = 0; i < binStr.length; i++) {
bin[i] = binStr.charCodeAt(i);
}
return bin.buffer;
},
};