Skip to main content

Register Credential & Sign/Verify

Register Credential

前后端数据传输:对buffer进行编码传输

https://github.com/GoogleChromeLabs/passkeys-demo/blob/fa4db9d0fd08689a346fa0715fd47834fbd8870f/public/client.js#L49-L66

前端:

参考这个项目:https://github.com/GoogleChromeLabs/passkeys-demo/blob/fa4db9d0fd08689a346fa0715fd47834fbd8870f/public/client.js#L117-L143

使用服务端 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

https://webauthn.io/#:~:text=Add%20WebAuthn%20to%20your%20site%20with%20one%20of%20these%20libraries%3A

java RegistrationValidationTest

https://github.com/webauthn4j/webauthn4j/blob/fb21d8f0ffface7f915812f6a5521ee2e38f724f/webauthn4j-core/src/test/java/integration/scenario/webauthn/UserVerifyingAuthenticatorRegistrationValidationTest.java#L81

AA sign

https://github.com/wevm/webauthn-p256/blob/f63da18143e22469800dd0fca28c78475ff07dec/src/sign.ts#L46

https://github.com/wevm/viem/blob/3749838fdd915ebccc56505ecd5a8047bfb8f38d/src/acc[…]-abstraction/accounts/implementations/toCoinbaseSmartAccount.tshttps://github.com/wevm/viem/blob/3749838fdd915ebccc56505ecd5a8047bfb8f38d/src/acc[…]-abstraction/accounts/implementations/toCoinbaseSmartAccount.ts

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(

https://github.com/wevm/viem/blob/1187827a512806da03cc6e3d8ecc408b4c0b0bab/src/account-abstraction/accounts/implementations/toCoinbaseSmartAccount.ts#L246-L251

https://github.com/wevm/viem/blob/1187827a512806da03cc6e3d8ecc408b4c0b0bab/src/account-abstraction/accounts/implementations/toCoinbaseSmartAccount.ts#L155-L158

) 编码转化成链上合约可用的数据,所以验签有两种方式

链上:直接用编码后的数据调用合约(合约需要,看上去要加一个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

其他参考

https://p256.eth.limo/

Credential encode

rawId encode 刚好是 Credential 的 id

alt text

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;
},
};