Developers: How we use SRP, and you can too

Donkey: Oh, you both have layers. Oh. You know, not everybody likes onions. Cake! Everybody loves cake! Cakes have layers!
Shrek: I don’t care what everyone likes! Ogres are not like cakes.
Donkey: You know what else everybody likes? Parfaits! Have you ever met a person, you say, “Let’s get some parfait,” they say, “Hell no, I don’t like no parfait”? Parfaits are delicious!

1Password uses a multi-layered approach to protect your data in your account, and Secure Remote Password (SRP) is one of those very important layers. Today we’re announcing that our Go implementation of SRP is available as an open source project. But first, I’d like to show you the benefits SRP brings as an ingredient in the 1Password security parfait.

Parfaits: delicious and secure

The first layer of security in 1Password, your Master Password, protects your data end to end – at rest and in transit – but we wanted to go further. The second layer is something we call Two-Secret Key Derivation. It combines your Secret Key with your Master Password to greatly improve the strength of the encryption. Thanks to your Secret Key, even if someone got your data from our servers, it would be infeasible to guess your Master Password.

That still wasn’t enough for us, though. When we first started planning how we were going to securely authenticate between 1Password clients and server, we had a wish list. We wanted to ensure that:

  • your Master Password is never transmitted or stored on the server.
  • eavesdroppers can’t learn anything useful.
  • the identity of user and server are mutually authenticated.
  • the authentication is encryption-based.

There was actually one other requirement that wasn’t exactly part of the list but applied to every item in the list: we didn’t want to roll our own solution. We know better than to roll our own crypto, and we wanted to find a proven solution that’s been around and has stood the test of time.

We wanted this layer to be just right.

SRP: a hell of a layer

It took us a while to find what we needed for this layer. (Apparently the marketing department of augmented password-authenticated key agreement protocols is underfunded.) But we eventually found SRP, which ticked all our boxes. SRP is a handshake protocol that makes multiple requests and responses between the client and the server. Now, that may not sound very interesting – and I’m not one to show excitement easily – but SRP is a hell of a layer. With SRP we can:

  • authenticate without ever sending a password over the network.
  • authenticate without the risk of anyone learning any of your secrets – even if they intercept your communication.
  • authenticate both the identity of the client and the server to guarantee that a client isn’t communicating with an impostor server.
  • authenticate with more than just a binary “yes” or “no”. You actually end up with an encryption key.

All this makes SRP a great fit for 1Password, and it keeps your data safe in transit. As an added bonus, because SRP is encryption-based, we end up with a session encryption key we can use for transport security (the fourth layer) instead of relying on just Transport Layer Security (TLS).

So that’s four layers of protection for your 1Password account: Master Password, Secret Key, SRP, and TLS. Now I’d love to show you how SRP works step by step in 1Password.

How 1Password uses SRP

Before any authentication can be done, the account needs to be enrolled. 1Password does this when you create an account. To use SRP, you’ll need a couple different things:

  • a key derivation function (KDF) that will transform a password (and, in our case, also your Secret Key) into a very large number. We’ve chosen PBKDF2.
  • an SRP group consisting of two numbers: one very large prime and one generator. There are seven different groups; we’ve chosen the 4096-bit group.

Enrollment

To enroll, the client sends some important information to the server, and the server saves it:

  1. The client generates a random salt and Secret Key.
  2. The client asks the user for a Master Password.
  3. The client passes those three values to the KDF to derive x.
  4. The client uses x and the SRP group to calculate what’s called a verifier.
  5. The client sends the verifier, salt, and SRP group to the server.
  6. The server saves the verifier and never transmits it back to the client.

Now the account is ready for all future authentication sessions.

Authentication

To authenticate, the client and server exchange non-secret information. Then the client combines that with a secret that only it knows and the server combines it with a secret only it knows:

  1. The client requests the salt and the SRP group from the server.
  2. The client asks the user for the Master Password and Secret Key.
  3. The client passes those three values (minus the SRP group) to the KDF to derive x.
  4. The client:
    1. Generates a random secret number a.
    2. Uses the SRP group to calculate a non-secret counterpart A.
    3. Sends A to the server.
  5. The server:
    1. Generates a random secret b.
    2. Uses the SRP group to calculate a non-secret counterpart B.
    3. Sends B to the client.

So A and B are exchanged, but a and b remain secrets. Through the power of math, the client (with x, a, B) and the server (with the verifier, A, b) can both arrive at the same very large number using different calculations. This is the number that 1Password uses as a session encryption key.

Verification

The last step is verification. After all, no amount of fancy math will help if the numbers don’t match up between client and server.

To verify, the client and server exchange encrypted messages:

  1. The client encrypts a message with the session encryption key and sends it to the server.
  2. The server decrypts the message and verifies it.
  3. The server encrypts its own message with the same session encryption key and sends it to the client.
  4. The client decrypts the message and verifies it.

If the client and server both used the correct inputs then they’ll both have the same session encryption key, which allows them to decrypt and verify the message. If they don’t use the correct inputs, everything fails.

The verification process proves to the server that the client has x, which can only be derived using the correct Master Password and Secret Key. It also proves to the client that the server has the verifier, which ensures that the client is communicating with the 1Password server, not an impostor.

Now that it has been verified, the session encryption key can be used to encrypt every message between the client and server going forward.

As you can see, it’s critical to remember your Master Password and keep your Secret Key safe if you ever want to authenticate your 1Password account. They’re also very important layers, after all. 🙂 And, like any good parfait, everything comes together to create something better than the individual layers alone.

Implement SRP in your own app

We love SRP so much that we want to see it used in more of the apps we use. That’s why we want to help you get started with SRP in your own project. Our Go implementation of SRP is available as an open source project:

This package provides functions for both clients and servers, and you only need to BYOKDF (Bring Your Own Key Derivation Function, like any good party). It’s the same code we’re using on our server and in the 1Password command-line tool, so we welcome security researchers to take a look and report any issues through the 1Password Bugcrowd bug bounty program.

SRP is one of the less appreciated parts of 1Password, and I hope I’ve explained it well enough for you to implement it in your own project. You can read more about how we use SRP in the 1Password Security Design White Paper. Leave a comment if you have any questions, or file an issue if you see something that can be improved.

Until next time, enjoy that parfait!

12 replies
  1. Puzzled User
    Puzzled User says:

    What effect does SRP have on the security of TLS? For example, there’s been examples of TLS / SSL being susceptible to leaking of secrets via leveraging the structure of the underlying data (e.g. CRIME, POODLE, etc.). Does SRP increase the risk of this? For example, by having predictable byte structures / format.

    Reply
    • Jeffrey Goldberg
      Jeffrey Goldberg says:

      We don’t know how TLS will break next, so it is hard to answer your very cool question with a high degree of confidence.

      CRIME involved a chosen plaintext attack, and there is no obvious way in which SRP could help out an attacker this way. My initial intuition is that it should make things harder. The fact that we have an additional encryption layer beneath TLS should make it harder for an attacker to inject chosen plaintext into things in a way that would be visible to the TLS layer. But that is just an intuitionistic hand-wavy argument. But one of our goals here is to keep user data secure even if TLS fails.

      POODLE is a different kind of dog altogether. It was a downgrade attack, and then a Chosen Chipertext attack on ciphersuites known to be vulnerable to CCAs. I don’t really see how any of the structure or content of what is being transmitted would affect those in anyway.

      I should note that we do think about downgrade attacks, and are very strict about our TLS configurations and own protocols because of this. 1Password users will have to keep their systems up to date, as would not like to weaken everyone’s security to accommodate those who aren’t able to keep their client systems relatively up to date.

      Anyway, thanks for that question. It gave me a chance to talk about some things that I find very interesting to think about.

      -j
      Chief Defender Against the Dark Arts @ AgileBits

  2. Melodiouscode
    Melodiouscode says:

    A very interesting article. One problem, those pictures are ice creams not parfaits! A parfait is a made from whipped cream, eggs, and fruit. Normally in a bar (gold brick) shape.

    Interesting to the developer in me, slightly annoying to the cook part of me. But worst of all now I want a parfait.

    Reply
    • Kate Sebald
      Kate Sebald says:

      I’m glad you enjoyed the article, but we’ll have to agree to disagree about the nature of a parfait. 😉 I can’t speak for other countries, but here in the U.S. yogurt parfaits are the most common type I see. These are layers of yogurt (plain or vanilla usually), fruit (either chutney or fresh), and sometimes granola or graham cracker crumbles. Toppings are a toss. I’ve seen whipped cream, a cherry, fruit syrup, wafers, or even nothing at all … it seems to be effectively chef’s choice on that front.

      These pictures unequivocally fit my experience of a blueberry yogurt parfait. Ice cream comes in a cone (waffle if you know what you’re doing). Unless its a sundae, but that definitely requires hot fudge, which is nowhere to be found here. Of course, I chose to write this reply when I have yet to eat lunch, so now I want your version of a parfait, my version of a parfait, and ice cream. Don’t suppose you’ve got a recipe for that bar-shaped parfait handy, do you? 🤤

  3. Ami Clueless
    Ami Clueless says:

    This looks a tad technical for me, but given that security is such an important topic:

    How do I install this new feature and where and how do I “enroll” (if that’s the term) my 1P please?
    You also say, you’ve chosen something called PBKDF2, should I just do the same and if yes, how do I go on about it?

    If you don’t mind me saying, your instructions are a little unclear.

    Reply
    • Jeffrey Goldberg
      Jeffrey Goldberg says:

      Hi Ami,

      You don’t have to do anything. We are just telling you about stuff that we are doing behind the scenes. When 1Password on your devices connects to 1password.com, 1password.eu, or 1password.ca this is what it is doing.

  4. Ami Clueless
    Ami Clueless says:

    Thanks Jeffrey, for clarifying this. Together with probably many others I was quite lost in this. I noted that you also now address this blog entry to Developers. One word can make such a difference. Thanks again.

    Without wanting to open a can of worms, somehow this confirms my view that a password security app should never even start to communicate over the internet. It’s highly complex to make that secure, and in complexity lies vulnerability. If we keep passwords local, there is one big concern less to worry about. Safer by design and so easy to do for the average Joe.

    Reply
    • Jeffrey Goldberg
      Jeffrey Goldberg says:

      Thanks, Ami.

      You might be interested in an article that covers some of the same ground that isn’t geared specifically for developers.

      You are also correct that it would be safer to never have your password data transmitted, other things being equal. If we all just used one single device on which we ever needed our passwords, then not transmitting anything would make the most sense.

      But people do need to use their passwords from different devices, and so we have designed 1Password to safely allow for that. We have three (or four, depending on how you count) layers of security for this.

      1. Your data is always encrypted with keys derived from your Master Password and Secret Key, both of which only you know or have.
      2. During transmission your data is also encrypted by the session key we get from SRP (as described in the article)
      3. During transmission your data is also encrypted by TLS/SSL.

      Number 1 on that list helps not only during transmission, but if the data is stolen from any place it is stored, including your own computer. In the early days of 1Password, we designed it with the expectation that people would have their computers stolen or data from their computers stolen. And so the same defenses that protect you if your data is stolen from your own device protect you if it is stolen from “the Cloud”.

      We have added an additional defense in case it is stolen from the cloud. That is the Secret Key. Your Secret Key is stored on your own device, but it is not stored on our servers. So that means that if someone steals your encrypted data from our servers, they would need to guess both your Master Password and your Secret Key. We call this Two-Secret Key Derivation (2SKD). So there is a very real sense that your 1Password data is safer in the cloud than on your own machines. (However, it is very very important that you don’t ever lose your Secret Key. Your data cannot be decrypted with out it.)

      So yes. Transmitting and remote storage of highly sensitive information requires lots of careful security design, but it is necessary (for a large majority of people) and some of that security design is just an extension of what we have to do to protect your data on your own computer.

      I hope this helps.
      -j

  5. Jake
    Jake says:

    So I’m one of the seemingly few trying to use SRP-TLS for my own app in Electron(so basically node.js with extra steps). What do you guys recommend doing once I’ve generated my SRP session key? I know that this somewhere down the line will be used to encrypt my TLS traffic but having trouble in setting up my handshake with my node server.(Also note I won’t be connecting to a node server in production I’m just using this as a nice sandbox) Hopefully I’m not totally off base here!

    Reply
    • Rick Fillion
      Rick Fillion says:

      Hi Jake,

      It’s great to hear that you’re trying to use SRP. Way to go. :)

      The result of SRP is really just a number, right. It’s a large number, which can be interpreted as bytes. In our SRP library, there’s a Key() function that will return a byte array based on the result of the SRP handshake. That byte array can then be used as the basis of an encryption key with something like an AES GCM key. If both sides do that, then they now have a symmetric key to encrypt/decrypt with.

      I hope that answers your question.

      Rick

  6. Jake
    Jake says:

    Phew, that’s actually what I’m implementing right now! Luckily I just have one request to make so manually encrypting and decrypting the request shouldn’t be too hard. Kind of a shame there isn’t greater support for TLS-SRP for web apps, and wouldn’t trust myself in changing the TLS handshake code to make it work:}

    Thanks Rick!

    Reply
    • Kate Sebald
      Kate Sebald says:

      Hey, Jake! Rick’s either on his way home from GopherCon or already there recovering from the week’s excitement, so on his behalf, you’re most welcome. 🙂

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.