通过Fido 2.0或navigator.credentials.get

时间:2019-01-30 20:52:49

标签: node.js fido-u2f

如何验证来自节点Web服务器上以javascript运行的“ navigator.credentials.get”的响应。

我已经使Fido2.0令牌正常工作并生成了响应,但是我不确定如何在Web服务器上对其进行验证。

我知道我必须使用公钥和签名来验证挑战,但是我不确定在节点中使用哪种加密模式或应该使用哪个库。

    function coerceToArrayBuffer(thing, name) {
        if (typeof thing === 'string') {
            // base64url to base64
            thing = thing.replace(/-/g, '+').replace(/_/g, '/');

            // base64 to Uint8Array
            var str = window.atob(thing);
            var bytes = new Uint8Array(str.length);
            for (var i = 0; i < str.length; i++) {
                bytes[i] = str.charCodeAt(i);
            }
            thing = bytes;
        }

        // Array to Uint8Array
        if (Array.isArray(thing)) {
            thing = new Uint8Array(thing);
        }

        // Uint8Array to ArrayBuffer
        if (thing instanceof Uint8Array) {
            thing = thing.buffer;
        }

        // error if none of the above worked
        if (!(thing instanceof ArrayBuffer)) {
            throw new TypeError('could not coerce \'' + name + '\' to ArrayBuffer');
        }

        return thing;
    }


    function coerceToBase64Url(thing, name) {
        // Array or ArrayBuffer to Uint8Array
        if (Array.isArray(thing)) {
            thing = Uint8Array.from(thing);
        }

        if (thing instanceof ArrayBuffer) {
            thing = new Uint8Array(thing);
        }

        // Uint8Array to base64
        if (thing instanceof Uint8Array) {
            var str = '';
            var len = thing.byteLength;

            for (var i = 0; i < len; i++) {
                str += String.fromCharCode(thing[i]);
            }
            thing = window.btoa(str);
        }

        if (typeof thing !== 'string') {
            throw new Error('could not coerce \'' + name + '\' to string');
        }

        // base64 to base64url
        // NOTE: "=" at the end of challenge is optional, strip it off here
        thing = thing.replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/g, '');

        return thing;
    }



let challenge = 'eJVGU35uQVHxcOVTypKh8xbPMHcKgC3JVvI9BHWALdpZkaIkIFhnXsADpRUmKzyyniQVJyj3TXm4_iycqKNyyw';
let userID = 'PTVW1ReUO1MoUwC71q2hHaZi4lbsYcaKcxPZikImYYN9gBJtnyy7phnkDOcoib_kSU3M98OZ_CmXINBc0FmYEBcecp-FS2ACcTIUnz2IdPcC5KRNoQrqxsExgbikmLXT';
challenge = coerceToArrayBuffer(challenge);
userID = coerceToArrayBuffer(userID);

let data = {publicKey:{
        'challenge':challenge,
        'timeout':60000,
        'allowCredentials':[
            {'id':userID,'type':'public-key'}
        ]
    }
    };

navigator.credentials.get(data).then((res)=>{
    console.log(coerceToBase64Url(res.response.authenticatorData));
    console.log(coerceToBase64Url(res.response.clientDataJSON));
    console.log(coerceToBase64Url(res.response.signature));
    console.log(coerceToBase64Url(res.response.userHandle));
    });

AuthenticatorData

SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAAIaQ

res.response.clientDataJSON

eyJjaGFsbGVuZ2UiOiJlSlZHVTM1dVFWSHhjT1ZUeXBLaDh4YlBNSGNLZ0MzSlZ2STlCSFdBTGRwWmthSWtJRmhuWHNBRHBSVW1Lenl5bmlRVkp5ajNUWG00X2l5Y3FLTnl5dyIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ

响应响应签名

MEQCIEeeSsO27uRwPXhYiZy9-Air6qiDw9V9gU7Dgv7poi8RAiBulG6PRqqbEiqFpQy7P_ujTQkfC532T5sCr0IsgwO3lA

0 个答案:

没有答案