4

I recently learned (read) the math behind RSA encryption (algorithm). Now, I wonder if there is a way to use a custom password instead of the private key.

Imagine a web application, where user signs up with a username and password. If a web application generates a public-private key pair at the server and store it themselves and uses it to encrypt user data, I would say, it lost its purpose. I mean, if anyone has access to the server's key-pairs, they can decrypt the user's data.

If the user's password acted like a private key, it would make sense, wouldn't it? So, How would one use a user's password as a private key?

4
  • 2
    Technically while you can use your password as the private exponent d, we don't use RSA or public-key cryptography for encryption. We prefer a hybrid cryptosystem. A random d in RSA makes the public exponent also random, so you dismiss the advantage of small public keys.
    – kelalaka
    Oct 28, 2021 at 12:03
  • 2
    RSA is not designed for encryption of large data. Instead RSA is used in a hybrid crypto system only to protect (encrypt) a (short) key which is then use for symmetric encryption. What you are trying to achieve is to encrypt data based on a password. No RSA should be used here in a first place, but instead a symmetric key should be directly derived from the password using a key derivation function (KDF), i.e. no involvement of RSA here. Oct 28, 2021 at 12:08
  • 2
    There have been systems where a password is used as the only source of entropy to seed an otherwise secure CSPRNG and then this CSPRNG is used to generate an RSA keypair. This makes keypair generation deterministic and repeatable. The security tradeoffs involved are generally worse than almost any other solution. See the excellent answer below for one such solution. Oct 28, 2021 at 15:05
  • Possibly related: security.stackexchange.com/questions/252199/…
    – Fax
    Oct 29, 2021 at 11:53

3 Answers 3

13

Imagine a web application, where user signs up with a username and password. If a web application generates public-private key pair at the server and store it themselves and use it to encrypt user data, I would say, it lost its purpose. I mean, if anyone has access to the server's key-pairs, they can decrypt the user's data.

There are a whole class of web applications where the server has zero access (or 'zero knowledge') of the users' secrets. See protonmail.com and sync.com for a few examples.

Generally, these applications work as follows:

At registration time, a uniform random symmetric key (key1) is generated from a CSPRNG using client-side scripting running in the user's web browser. The user chooses a good password ( preferably dicewire or Bip39), and another symmetric key (key2) is derived from this password using a password based key derivation function (such as PBKDF2, Argon2, etc). Then, key1 is encrypted using key2 in-browser, then encrypted key1 is stored on the server.

When the user logs in, encrypted key1 is downloaded to the user's web browser. The user provides the password, key2 is derived from the password, and encrypted key1 is decrypted in-browser. key1 is used to encrypt all the user's secrets in-browser, so that only the encrypted secrets are uploaded to the server.

This is a slight over-simplification, because there is also a salt involved (which is stored on the server) in the password-based key derivation process. But, this is the general idea as to how web-based zero-access systems work.

2
  • 1
    key1 is usually called the Key Encryption Key KEK and key2 is called the File Encryption Key FEK ( though not common as KEK). If the users password is weak, the uniform random key is not going to protect them!
    – kelalaka
    Oct 28, 2021 at 20:27
  • 1
    And note that, with this users can change their passwords, and wiping the data is imminent, just delete FEK!
    – kelalaka
    Oct 29, 2021 at 21:58
6

First of all: As a general rule, you never generate the private key on somebody else's computer. The key pair is generated locally, and the public key is the only part sent anywhere.

While it's probably possible to create a system for deterministically but securely generating a private key from a password, there's a much simpler approach. Generate a key pair locally, and then encrypt the private key using a symmetric key derived from a word. Then it's possible to store both the public and (encrypted) private keys on the server, and as long as the server never sees either the password-derived key or the password itself (in plain text), then the server can't ever decrypt the private key (but the user can, if they enter their password into the client).

4
  • 1
    Nice answer. I am making an app using exactly this approach where the privKey is encrypted using a pw-derived key (using PBKDF2) and stored on the server. But my question is: Is this considered Zero-Knowledge? Given a weak user password, whoever has access to the stored encrypted private key can still perform an offline attack on the password and probably crack it pretty fast. I'm therefore being critical of my own system and recently was thinking about a different solution (I wanna be able to legitimately call it zero-knowledge/e2ee in the end) Oct 29, 2021 at 16:26
  • Are you suggesting encryption with RSA? As you might know that we prefer hybrid-cryptosystems that are faster and also better for the environment!
    – kelalaka
    Oct 29, 2021 at 18:39
  • 2
    @kelalaka As a practical matter, you need to use symmetric or hybrid crypto if protecting anything of length. You can only go fully symmetric if you don't need to be able to share things with third parties at any kind of scale. The issue - both in general and specific to this question - is how to secure the private key. How it's used later (for securing the user data) is another good question, but not really what's being asked here.
    – CBHacking
    Nov 1, 2021 at 21:24
  • 1
    @csstudent1418 End-to-end encryption with a weak key is still zero-access, although obviously you want to do what you can to avoid weak keys (including keys derived from weak passwords). There are lots of ways to ensure better password quality, such as checking candidate passwords against the lists of known breached passwords, but at the end of the day your only option that doesn't require relying on user passwords instead requires the user to transport their own secure private key (or secret key, if pure-symmetric) between devices themselves (or only support one client device).
    – CBHacking
    Nov 1, 2021 at 21:27
5

How would one use a user's password as a private key?

There is a generic method that will work for many different algorithms:

Seed the CSPRNG with the user password.

The key generation for RSA and similar algorithms is based on selecting random primes. By seeding the pseudo-random generator with the password, it will generate same random number each time.

That way you can regenerate the key whenever it is needed, using whatever algorithm is used for the key generation normally. The security level will be equivalent to the user password, and bruteforcing can be slowed down by applying a key-derivation function to the password before using it as a seed.

But the whole approach has a severe downside: you cannot change the password without changing the public key also. For that reason it is usually better to store the keys separately and just encrypt them with the password.

3
  • Clever, as long as all aspects of key generation are deterministically random (e.g., the Miller-Rabin witness primality test must use the PRNG in the same way). Another option is XOR the private key with the output of PBKDF2, faster too.
    – Russ
    Jun 30, 2023 at 14:32
  • @Russ XOR only works for algorithms where the key can have arbitrary random value. For many asymmetric cryptosystems it would corrupt the key pair.
    – jpa
    Jun 30, 2023 at 14:42
  • 1
    let me clarify - given a keypair, you can PBKDF2 a string, then xor that with the pristine (original) private key, then could release the xor'd private key. The user would have to PBKDF2 their password, and xor again to recover the pristine private key. This is to protect use of the private key.
    – Russ
    Jul 14, 2023 at 16:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .