Git Product home page Git Product logo

bitid's Introduction

BitID

Bitcoin Authentication Open Protocol

Pure Bitcoin sites and applications shouldn’t have to rely on artificial identification methods such as usernames and passwords. BitID is an open protocol allowing simple and secure authentication using public-key cryptography.

Classical password authentication is an insecure process that could be solved with public key cryptography. The problem however is that it theoretically offloads a lot of complexity and responsibility on the user. Managing private keys securely is complex. However this complexity is already being addressed in the Bitcoin ecosystem. So doing public key authentication is practically a free lunch to bitcoiners.

Video demonstration of the user flow :
https://www.youtube.com/watch?v=3eepEWTnRTc

Slides presentation of the project :
http://bit.ly/bitid-slides

Implementation example (server) :
http://bitid.bitcoin.blue

Implementation example (client) :
https://github.com/antonio-fr/SimpleBitID

The protocol is described on the following BIP draft and is open for discussion :

https://github.com/bitid/bitid/blob/master/BIP_draft.md

Application examples

Website authentication

  • any bitcoin core website (mining pools, related services, otc exchanges…)
  • content websites such as forums and wikis, including access control
  • decentralized 2FA

Real world applications

  • door access controls
  • lockers rental

E-commerce

When paying for something on the internet, the wallet can save meta-data from the transactions (based on BIP70 payment request). If I need to access again to my order (change of address, download again the file...) then I identify using the originating address for this transaction.

There is therefore no need to create an account prior to the payment, reducing the friction and upping the transformation rate for the merchant.

See BIP70 extension proposition as well as BitID metadata for more information.

Security concerns

BitID offers a secure authentication method :

  • As secure as sending funds through Bitcoin
  • out-of-band, keyless authentication using a smartphone wallet, allowing login through an untrusted computer
  • anti-phishing protection when using a desktop wallet (IP address matching verification)
  • no third party, no external compromission possible, no storage of user sensitive data on the server
  • resistant to arbitrary signature requests: challenges are syntaxically verified by the wallet as valid bitid URIs
  • resistant to brute force or dictionary attacks

However many responsibilities are in the hands of the user :

  • the user must protect his private keys and make backups (this should already be the case)

  • the user must pay attention to the URL shown in authentication requests in order to avoid man-in-the-middle attacks; the out-of-band authentication process does not allow any protection against these attacks.

  • Finally, a major drawback of this protocol is the absence of revocation procedures. If the user loses her private key or if it is compromised, there is no native possibility of revoking the authentication access. The only way to revoke the user's identity is then to to establish a back-channel communication with the website using email, security questions, or a password.

General remarks

BitID is not a general-purpose identification system. It should mainly be used when a Bitcoin address is paramount to the usage of the site or application, and when this usage is a long-term one - it wouldn’t make sense for a tipping service.

Therefore, BitID doesn’t claim to be a superior authentication system, just one well-fitted to Bitcoin and altcoins-related applications.

Implementation

Wallet implementation requirements

To be compatible with the BitID protocol, a wallet must implement the following:

  • register the bitid scheme
  • throw a bitid intent when scanning a BitID QR code (if applicable)
  • decode the URI and verify its format
  • display a request for authentication showing the domain name callback and ask for validation
  • ask the user to pick up or create a Bitcoin address for the authentication (show the last Bitcoin address used if this is a known callback address)
  • sign the BitID URI with the private key (using the \x18Bitcoin Signed Message:\n#{message.size.chr}#{message} convention)
  • POST the signature and the public key to the callback URL
  • completion dialog : success/retry/cancel

Specs and UX should be the most simple possible in order to bring on board the developers of the most used wallets.

Android Bitcoin wallet implementation :
https://github.com/bitid/bitcoin-wallet

Airbitz Bitcoin wallet implementation :
https://airbitz.co/bitcoin-wallet

SimpleBitID (python client) :
https://github.com/antonio-fr/SimpleBitID

BitID Authenticator (Android) :
https://play.google.com/store/apps/details?id=com.skubit.bitid (app)
https://github.com/skubit/bitid-android (source)

Ledger Wallet Chrome app (Chrome/Chromium) :
https://www.ledgerwallet.com
https://github.com/LedgerHQ/ledger-wallet-chrome (source)

Backend implementation requirements

To be compatible with the BitID protocol, a server application must implement the following :

  • Create a callback route
  • Generate a complex enough nonce (match it to the session and timestamp it)
  • Generate an URI with the nonce and the callback URL
  • Display the corresponding QR code
  • On receiving the POST, verify the signature with the user's public key
  • If correct, login the session with the Bitcoin address and notify the front-end using sockets
  • Store the public key as the user identity, allowing for storing user preferences and additional data
  • Alternate version for zero-day compatibility :
    • display a form with the following fields: generated nonce, Bitcoin public address and signature
    • when submitting, verify and return to login or error

Ruby implementation :
https://github.com/bitid/bitid-ruby (Gem)
https://github.com/bitid/bitid-demo

Python implementation :
https://github.com/LaurentMT/pybitid
https://github.com/LaurentMT/pybitid_demo
https://github.com/LaurentMT/pybitid_2fa_demo

Javascript implementation :
https://github.com/porkchop/bitid-js
https://github.com/porkchop/bitid-js-demo

PHP implementation :
https://github.com/conejoninja/bitid-php
http://vps.madriguera.me/bitid-php/ (demo)
http://wordpress.org/plugins/bitid-authentication/ (wordpress plugin)

Credits

Eric Larchevêque [email protected] (protocol, Ruby)
@LaurentMT (Python)
Aaron Caswell [email protected] (Javascript)
@_CONEJO (PHP)
Antoine FERRON antonio-fr (SimpleBitID client)

bitid's People

Contributors

ericlarch avatar laurentmt avatar manuelvalente avatar paullinator avatar puggan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bitid's Issues

Require Access-Control-Allow-Origin header in callback

It is needed to support CORS in order to make browser-based bitcoin wallets be compatible with BitID (aka Coinpunk, GreenAddress, Darkwallet...).

The solution is to add the following header in the callback responses:

Access-Control-Allow-Origin: *

Status?

What is the status of this protocol? Is it being developed/review?
If not, what are some recommendations you can make for an alternative PKI authentication?

Some Thoughts

I recently was considering creating a bitcoin-esque authentication system for websites, in the hope that it could eventually replace passwords online. After fleshing out my concepts, I performed a Google search, and stumbled across the BitID project. First off, I love the idea. I can see this going somewhere, and I want to contribute to the codebase. However, I would like to note a few thoughts about my implementation ideas, and see what you think of them.

  • A public-key authentication framework does not, by necessity, need to have any sort of divisible unit associated with it. BitID (currently) is a system currently built on top of the Bitcoin/Namecoin ecosystem, and for better or for worse, the currency metaphor sticks with it. In my opinion, the "ideal" decentralized authentication framework would allow any user to create an account at any time, register on any site, and have the system work, without needing to seed an account with currency at any step in the process.
  • Bitcoin uses a Blockchain to store transactions, and ensures security by a Proof-of-Work. This security is necessitated with Bitcoin, to prevent malicious actors from "unspending" transactions via an overturning of work done previously. A malicious actor can never spend Bitcoins that do not belong to them (with the caveat of overturning the work performed to mine the original block minting those coins), as they do not possess the private key of addresses they do not own. If we take into consideration a secure distributed system without an exchange of value, neither a Proof-of-Work nor a global ledger of all accounts are required. This system, which I will refer to as "Proof-of-Identity", is remarkably similar to PGP.
  • Why is a global ledger of accounts not necessary for a secure authentication system? Simple: Any website attempting to determine the authenticity of a user will have a public key on record for that user, along with at least one endpoint (decentralized or central) for revocation. If the user can provide proof that they control the underlying private key, and that key has not been revoked, no further confirmation is required.

I'm seeing utilization of Bitcoin and Namecoin as sort of a 2FA in this system, but the system itself could (and, I argue, should) exist external to those blockchains, as a currency metaphor is unwieldy, and ill-suited for the purposes of proving an identity.

BitID should optionally provide some predefined info about the user

It would be great to provide some basic info about the user when you register in a new web page, as preferred username, email...

It could be requested as GET params in the bitid: uri and returned the data in the /callback response.

For example:

bitid://bitid.bitcoin.blue/callback?x=dda88447c4cec090&request=email,username

and then in the response:

{"uri" : "bitid://bitid.bitcoin.blue/callback?x=5590310e900d94f8&u=1", 
    "address" : "", 
    "signature" : "",
    "data": {
        "username": "foo",
        "email": "[email protected]"
    }
}

EDIT:
These are the standard claims in OpenID.

Add arguments to request personal information

We'd love to have BitID incorporate the ability for a website/service to request personal information from the wallet for creation of an account. It is still up to the wallet to send or not send the information. An example would be to request, name, email, & phone number by appending arguments to the BitID URI.

ie. bitid:https://mywebsite.com/?token=12345&name=&addr1=&ph=&email=

Since there's no space to put requested parameters before the callback URL, I propose (but am very open to alternatives) that the presence of specific empty parameters in the callback URL signify that the wallet can optionally fill in the parameters, URI encoded, if the user chooses to send the info to the website. The callback can then be something like

https://mywebsite.com/?token=12345&name=Jerry%20Smith&ph=%2B1-619-553-2359&email=jerry1f%40gmail.com

Thoughts?

PS, we love BitID and we at Airbitz intend to support and promote the protocol in the very near future.

Same PubKey for every website?

Hi.

I was wondering if BitId uses the same ID Key for every website or does it have site specific IDs like SQRL protocol?

SQRL IDs are both user AND site specific: Although the same user always presents the same ID to the same site, they present an entirely different ID to every other site they visit.

source: https://www.grc.com/sqrl/sqrl.htm

Thank you very much.

Scope and contemporary services

The current metadata specification lists twitter handles and facebook names as possible fields. While both of these services are heavily in use today they are not guaranteed to be so forever and updating a protocol specification to match contemporary cultural usage seems troublesome.

I feel a better approach would be to merely have a request for social media accounts, and the user sends key-value pairs in the response, one for each social media account they would like to disclose.

"Finally, a major drawback of this protocol is the absence of revocation procedures."

The need for revocation is based on the possession of a single authoritative secret key. HD means if one key (not the master clearly) is revealed, then a new secret key can be used, from the "index" variable.

Even if the master seed is revealed, the user can have a user per site secret that they use to re-establish their connection with the user information stored at the site (perhaps when the site verifies itself to the client during set up), or better, the user's site status is stored by the user.

Mostly I just want to use BitID to open my door, login to Linux, etc. etc. At the low end there's a lot of fruit waiting for something this simple, this tested, and without all the complexity of systems that have been around a long time without adoption.

If you can run a wallet, most can, you can handle BitID (which I consider a little obfuscated already without the option to choose the key pair).

SGML was wonderful but it needed HTML to democratise it. Cryptographic authentication might be at that point, where PGP gives way to a more consumer friendly BitID.

All the parts, demand as breaches reach a crescendo, cheap as chips chips, experience, innovation and incentive around Bitcoin, and a growing appreciation by users of the fact sites will not protect them, they need to assume the responsibility.

Once everyone has a "wallet" for authentication, experimenting with Bitcoin becomes much easier... Other "wallets" are being developed, imho, unnecessarily, https://medium.com/mit-media-lab/what-we-learned-from-designing-an-academic-certificates-system-on-the-blockchain-34ba5874f196.

While I wouldn't want all my eggs in one basket, if that basket can be reliably secured and is well understood by frequent use, that is the better basket.

In the response, provide a target url?

I've added BitID to my Bitcoin wallet (iOS) and the mobile experience is somewhat cumbersome.

If you visit a BitID enabled site, it would be nice if there was a bitid:// href you click, which could launch the BitID enabled App that can sign challenges, which asks the user if they'd like to sign in, and once they have, be able to bounce the user back to the browser to the website URL that originally sent them there (would likely result in 2 "tabs" with the same content) or a URL that would set their necessary session cookie and then bounce them to the page they should go to.

I think there may be some security concerns that need to be addressed with this method, but a smooth mobile experience seems important... It may also complicate the server side... Hmm...

Addresses format for BitId

Till now, the BitId protocol doesn't specify explicitly which kinds of addresses can be used within the protocol. Current implementations manage standard bitcoin addresses (1...) but additional formats exist in the bitcoin ecosystem, like stealth addresses (BIP63) or pay-to-script-hash (BIP13).

Each format comes with its specificities:

  • Standard bitcoin addresses embed the hash of a public key (public key can't be retrieved from the address)
  • Stealth addresses embed two public keys which can be retrieved from the address
  • Pay-to-script-hash addresses embed the hash of a script which is used to redeem transactions (the script can refer to one or several public keys and public key(s) can't be retrieved from the address).

I think the protocol should make clear which kind of addresses can be used.

An alternative could be the definition of a specific format for the protocol.

Cons:

  • The protocol can't rely on addresses used in transactions and appearing in the blockchain.

Pros:

  • A specific format could allow advanced scenarii like "m-of-n signatures for auth":
    • 2-of-2 sig => user owns 2 private keys associated to the address. One private key is stored in the hot wallet. The second key is stored offline. Requires a manual interaction but provides a high level of security.
    • 2-of-3 sig => user owns 2 private keys. The website owns a third private key (stored offline) which can be used if the user has lost one of her keys.
    • M-of-M sig => resource can be accessed if and only if all participants are present and agree to access the resource ("when Bob is alone, he always eat all the food that we let in the fridge" ;).

BitId and Real Time Phishing

Hi everybody,

This entry is not for an issue but for an open discussion. During my spare time, I've tried to dive deeper in the subject of Real-Time Phishing.

I'm interested in this kind of scenario:

  • Three actors :
    • User : uses a web browser and a bitcoin wallet
    • Server : the legit service
    • Attacker : tries to mislead the others actors and to gain user's access rights against the server
  • Workflow:
    • step 0 : Attacker initiates the process by a phishing email (or any other technic leading User to communicate with Attacker while thinking she speaks to Server).
    • step 1 : User sends a request to Attacker to get a BitId challenge (but thinks she communicates with Server)
    • step 2 : Attacker sends a request to Server to get a BitId challenge
    • step 3 : Server generates a BitId challenge and returns the challenge to Attacker
    • step 4 : Attacker returns the challenge to User (browser)
    • step 5 : challenge is forwarded to User's wallet
    • step 6 : User signs the challenge and sends it to Server. Server validates the challenge. (/callback request)
    • step 7 : Attacker completes authentication against server with User's account (/auth request).
    • step 8 : User tries to complete authentication but is fooled by Attacker ("service temporary unavailable", ...)
    • step 9 : Attacker does what she has to do with Server using User's account.

This kind of attack is not specific to BitID. It also works with authentications by login/password or by login/password + 2FA (and I guess it's actually exploited). I think that BitId is already more secure than existing schemas but I wonder if we could make it much more secure and especially against phishing attacks.

Here are a few hypothesis and "axioms" that I use:

  • During authentication, we shouldn't trust anything sent by Server and received by the browser, except the BitId challenge.
  • We shouldn't rely on IP addresses at HTTP layer. They can be tampered by Attacker.
  • We should avoid, as much as possible, solutions requiring installation of a plugin or an addon in the browser.
  • Channel established between the wallet and the server looks like our secure channel in the case of this attack. Of course this channel could also be attacked by a MITM but I think there's existing solutions to reinforce the security of this channel (ECDH + messages encryption).

Till now, the "best" solution I've imagined is following :

  • Step 0 to 5 are identical to previous scenario
  • step 6 : User signs the challenge and sends it to Server. Server validates the challenge but does not consider that authentication is completed. In place, it generates a random key and returns the /auth uri to Wallet. The /auth uri is enriched with a parameter which is the random key.
  • step 7 : Wallet opens the /auth uri enriched with the BitId challenge in a new browser window. Server checks that random key and BitId challenge are valid and associated. If it's ok, user is authenticated.
    This solution relies on the fact that we can trust the initial BitId challenge (if attacker tampers this challenge, authentication can't complete and attack fails) and that we consider the Wallet-Server as a secure channel.

Anyway, I'm not satisfied with this solution because it has a major UX flaw:

  • if Wallet is on the same computer as Browser, it will open a new windows. Not really nice but well...
  • if Browser runs on a computer and Wallet runs on a smartphone, it implies that User starts her browsing on a computer and finishes it on a smartphone... Quite bad :(

Work in progress but insights, comments, ideas are welcome !

Laurent

Make bitid as similar to OAuth as possible

Hi,

As there's already (kinda) a standard for authentication without a password, I think that bitid could be more like a OAuth-like provider. What are your thoughts on this?

Congratz on a very cool idea!

Esteban

FWIW: submitting address is not strictly required

After a Bitcoin address is chosen, or created on the fly, the full bitid URI is signed with the address’ private key. The signature and public key are then POSTed to the callback url.

Actually it looks like bitid.bitcoin.blue POSTs the public-key-hash, not the public key, but that aside, doing so in general is not strictly required. Since the message as well as a signature is given, the public key (or address) might be derived based on that.

https://github.com/scintill/php-bitcoin-signature-routines/blob/master/verifymessage.php#L20 L20-L59 can be used to do so.

Just wanted to let you know. Not sure, if it would make sense though from an data integrity point of view for example.

Cheers!

Support for session expiration informacion

As a client trying to authenticate with the server, I may be interested in knowing when is the expiration date of my credentials. This can easily handled by returning a "expires" field when the authentication is finished.

bitcoin-wallet, bad json = crash

trying to implement bitid, and exidently sent a php-print_r to my android, insted of the log file, as the answer to a callback, and that crashed the app.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.