Corporate Adoption of TAPSIGNER for 2-Factor Authentication

Corporate Adoption of TAPSIGNER for 2-Factor Authentication

By Patrick McLaughlin (guest author) The original thread on X that inspired this article can be found here


When Megawatt began selling energy into the PJM market, we had to manually submit complicated day-ahead and real-time offers in an outdated web UI. This was not scalable, so we immediately began automating the process and writing a custom app to simplify submitting manual offers in a user-friendly GUI.

Submitting offers was now incredibly easy, but this inevitably raised concerns around how we should secure the app. After all, an attacker could potentially offer energy at $0/MWh and shut down our miners when the market accepts the offer. The solution, of course, was implementing 2-factor authentication.

There are three common types of 2-factor authentication:

  • Hardware Key
  • Authenticator App
  • SMS Verification

The pitfalls of SMS verification are well known, and it is hard for me to be inspired by anything non-Bitcoin like an authenticator app, so those options were out. The only option remaining was the most secure one anyway: hardware keys.

I was aware of TAPSIGNER and I knew these devices signed transactions, but I had never used one before. Because transaction signatures, or message signatures in this case, are simply random numbers fed into an elliptic curve calculation that each produce a single, easily-verified result, I suspected TAPSIGNERs could be used as our second authentication factor.

To investigate further, I went straight to the TAPSIGNER docs on the Coinkite website and found this list:

Coinkite was already ahead of me. Confident I could now make this work, I started the implementation.

Reviewing the Implementation

Eagle-eyed readers, be on the lookout for where we violate the TAPSIGNER Best Practices recommended by Coinkite. We’ll discuss the trade-offs at the end of the article.

In app development, you generally have a front-end application that exchanges data with a back-end server. The front-end application (app) is stored on the user’s device. The back-end server is owned, controlled, and maintained by the company that created it. The app makes requests to the server whenever it needs some information. In our case, the users are Megawatt employees and/or customers that license our Demand Response software, and the company that owns & maintains the back-end server is Megawatt.

Logging In

Users login to the mobile app with a traditional username and password. After our server authenticates your username and the hash of your password, a digest/nonce is calculated. The digest is a random, 32-byte number in hexadecimal format that should only be used once. It can be a different size, but what is important is the digest is random and large. A new digest is calculated and stored on the server every time the user logs in. The server then returns the digest and the TAPSIGNER PIN/CVC code to the mobile app.

Scanning the TAPSIGNER

With the digest and PIN code received, the mobile app then prompts the user to scan the TAPSIGNER. After a certificate check to verify the authenticity of the card, the TAPSIGNER signs the digest and the signature is returned to the server.

Verifying the Signature

Our server uses a secp256k1 implementation to verify the ECDSA signature against the digest and the master xpub (public key) of the TAPSIGNER. If that signature is valid, the user is authenticated.

Best Practice Violation

Did you catch the Best Practice violation? Here’s a quick overview of the process:

Never store a PIN code! We’re storing it on our server to provide a better user experience (UX) when scanning the TAPSIGNER. After entering a username & password, you wouldn’t want the user to then have to manually enter the PIN on their phone. By storing the PIN, we simplify the workflow to just scanning the TAPSIGNER. If an attacker had your TAPSIGNER, they would still need your username & password to authenticate with our server and vice versa. Since we are not securing funds with these TAPSIGNERs and they are only used for 2-factor authentication, the Best Practice violation seems like a reasonable trade-off for this use case.

Alternative Workflow

We could use the TAPSIGNER alone for authentication. The user scans it, enters the PIN in their mobile app, and the server authenticates the signature, eliminating the need for usernames and passwords altogether. If the user lost his TAPSIGNER, an attacker would still need to know the PIN to authenticate, which is not stored on the company server in this scenario. The UX is really smooth for the user, and this workflow mirrors the FIDO2 standard.


The FIDO (“Fast IDentity Online”) Alliance is an open industry association whose stated mission is to develop and promote authentication standards that “help reduce the world’s over-reliance on passwords”.1 FIDO2 is the World Wide Web Consortium’s (W3C) Web Authentication specification2 that enables users to leverage common devices to easily authenticate to online services in both mobile and desktop environments. FIDO2 addresses the lack of interoperability among devices that use strong authentication and reduces the problems users face creating and remembering multiple usernames and passwords.3

The FIDO protocols use standard public key cryptography techniques to provide stronger authentication. During registration with an online service, the user’s client device creates a new key pair. It retains the private key and registers the public key with the online service. Authentication is done by the client device proving possession of the private key to the service by signing a challenge. The client’s private keys can be used only after they are unlocked locally on the device by the user. The local unlock is accomplished by a user-friendly and secure action such as swiping a finger, entering a PIN, speaking into a microphone, inserting a second-factor device or pressing a button.4

Does this process sound familiar? With our TAPSIGNER implementation, we are essentially following the FIDO2 standard, but without the certification. Certifying the TAPSIGNER as a 2-factor authentication device could be a possible new business line for Coinkite, enabling them to be used to authenticate with companies like Google, Apple, and Amazon.5

Closing Thoughts

If you are using SMS verification or an authenticator app for 2-factor authentication within your company, consider adding TAPSIGNERs to your arsenal! They are inexpensive, their security is based on the widely tested elliptic curve cryptography of secp256k1, and they grant the same security assurances as defined in the FIDO2 standard.

*The code examples have been modified, censored, and commented specifically for this article.

Coinkite Team

We, at Coinkite, are very excited to see how the Bitcoin industry continues to use our products as primitives in new use cases. Megawatt’s demonstration of Tapsigner as 2FA highlights how the Bitcoin industry is maturing in its ability to solve its own needs. Traditional cybersecurity heavyweights such as RSA and Yubikey lack support for Bitcoin’s Secp256k1 Eliptic Curve. We believe Bitcoin’s Eliptic Curve is the most battle hardened, under appreciated, and therefore greatest potential signing curve for use in today’s global internet native economies.

Follow Coinkite and TAPSIGNER on X to stay up to date with their products! GitHub repositories for sample TAPSIGNER Javascript code -> cktap-protocol-react-native and CkTap-Demo For further inquiries or to connect with the author, please reach out on X at @boilerhodl or NOSTR at npub14y9984l32yr3jna9gsh5lz9l6l2yp3uxx8nxrav6u3jcr8duhhhqzg8xet.