Verifying a Yubikey for genuity using common tools
I received a free Yubikey from an untrusted source on the CCCamp 2019.
Therefore I looked for a way to verify its authenticity. The device appeared physically to be an original and not tampered with.
A check whether the key was manufactured by Yubico seems like a sufficient way to make sure that the security key is an original.
The next method goes a little bit deeper into how WebAuthn works internally.
We start by getting a WebAuthn response from our Yubikey. Even tough there are probably cooler ways I just got it from the Yubikey WebAuthn demo site. After registering you key there you can get the response in the technical details:
Using the MIT licensed code by Ackermann Yuriy we are able to verify the signature ourselves. Props go to him for reading all those RFCs!
The following functions and imports are needed in order to get the data, signature and certificate used in the attestation in WebAuthn:
letattestationBuffer=base64url.toBuffer(webAuthnResponse.response.attestationObject)letctapMakeCredResp=cbor.decodeAllSync(attestationBuffer)letauthrDataStruct=parseAuthData(ctapMakeCredResp.authData)if(!authrDataStruct.flags.up)thrownewError('User was NOT presented durring authentication!')letclientDataHash=hash('sha256',base64url.toBuffer(webAuthnResponse.response.clientDataJSON))letreservedByte=Buffer.from([0x00])letpublicKey=COSEECDHAtoPKCS(authrDataStruct.COSEPublicKey)letsignatureBase=Buffer.concat([reservedByte,authrDataStruct.rpIdHash,clientDataHash,authrDataStruct.credID,publicKey])letPEMCertificate=base64ToPem(ctapMakeCredResp.attStmt.x5c.toString('base64'))letsignature=ctapMakeCredResp.attStmt.sigconstpemStream=fs.createWriteStream('certificate.pem')pemStream.write(PEMCertificate)pemStream.end()constsignatureStream=fs.createWriteStream('signature.sig')signatureStream.write(signature)signatureStream.end()constdataStream=fs.createWriteStream('data')dataStream.write(signatureBase)dataStream.end()
We also need a root certificate by Yubico again which will be used to verify the chain: