1

I'm developing an application which will need to derive a private/public key pair from a user provided password, and then use the public key to encrypt some text (up to 1000 characters in length) such that it can only be decrypted by the paired private key. The password and private key will not be stored anywhere, so that nobody with access to the database can decrypt the text without the users' password. I know that I will need to use a KDF algorithm to generate the key, and some sort of public key encryption algorithm to encrypt/decrypt.

I know that there are several secure algorithms, but also several algorithms which are considered cracked and insecure. What are the most secure algorithms I can use for the KDF and encryption? What best practices should I follow to ensure that the data is as secure as possible?

I will be using the Java standard library implementations of the cryptographic algorithms.

vikarjramun
  • 121
  • 5
  • 5
    You essentially ask for a deterministic creation of a key pair based on some password, which is a possible duplicate of [Password based Asymmetric Key generation](https://security.stackexchange.com/questions/116126), [Generating deterministic X.509 certificates?](https://security.stackexchange.com/questions/61845/). And there is no *"__most__ secure"* algorithm for this. The security of this idea mainly depends on the quality of the user password and the inherent slowness of the KDF. The slowness of the KDF can usually be tuned to arbitrary values by adding more rounds. – Steffen Ullrich Sep 24 '19 at 06:51
  • As you do not store keys, why not use a symmetric key? I feel like an AES key would be more convenient to derive from a password and will lead to faster encyption/decryption. – Lou_is Sep 24 '19 at 08:56
  • If you need to encrypt up to a 1000 characters you'll need to use RSA 8192 if you go with public key encryption. However, public key really doesn't seem to give an advantage over symmetric. I suggest you consider Lou's suggestion and go with AES (GCM). – Swashbuckler Sep 24 '19 at 19:46
  • @Lou_is I actually *do* need to use asymmetric encryption, because one user may need to encrypt text using the public key of another user, without being able to decrypt messages of that other user. – vikarjramun Sep 25 '19 at 02:46
  • @Swashbuckler I'm not sure I understand, why does the key size need to increase if the length of the plaintext increases? Could RSA 2048 work with 1000 characters of text, albeit a little less secure? How less secure would it be? – vikarjramun Sep 25 '19 at 02:49
  • @SteffenUllrich I just realized that PBKDF seems to give a symmetric key, not an asymmetric key. What is the best way to generate an asymmetric key from a password/secret? – vikarjramun Sep 25 '19 at 02:54
  • @vikarjramun: *"What is the best way to generate an asymmetric key from a password/secret?"* - the relevant links for this are already included in my first comment. I see no need to repeat myself. – Steffen Ullrich Sep 25 '19 at 03:02
  • @SteffenUllrich would you say it is relatively secure if I used the hashed password as the seed of a PRNG and used it to generate primes for RSA? – vikarjramun Sep 25 '19 at 03:13
  • @vikarjramun: *"would you say it is relatively secure ..."* - there is no __relatively__ secure (your last comment) as much as there is no __most__ secure (your question). __Relative__ always needs some frame of reference and you don't provide one. Other than that kind of idea is already in the links I've provided so there is no need to discuss it here again. – Steffen Ullrich Sep 25 '19 at 03:26
  • @vikarjramun With RSA the size of the message, including padding, has to be smaller than the modulus. Take a look at https://stackoverflow.com/questions/5866129/rsa-encryption-problem-size-of-payload-data – Swashbuckler Sep 26 '19 at 15:58

2 Answers2

1

Personally, as public key cryptography goes, I think RSA should be used. There are multiple reasons for this:

  • RSA has been proved secure by many people

  • RSA is widely used and implemented, therefore info is widespread

  • RSA is theoretically quantum proof, provided you use a large enough key

  • RSA keys can be multiple sizes

You could use Elliptic curve cryptography if you wanted though.

KDF's

As KDF's are concerned, PBKDF2HMAC is the most used standard. Argon2, Scrypt and AES-KDF are also widely used though.

Currently all of my apps use PBKDF2HMAC, but I am migrating to Scrypt because it is more secure.

Legorooj
  • 111
  • 4
0

You just need to hash your password once with a secure algorithm

I will develop my statement using Elliptic Curves as they are as robust as RSA for smaller keys (256bits for EC and 3072bits for RSA give the same security), and faster to compute. Also, RSA key requirements differ as you need to find primes.

In Curve25519 paper you have this for private key generation:

Computing secret keys. Inside your program, to generate a 32-byte Curve25519 secret key, start by generating 32 secret random bytes from a cryptographically safe source: mysecret[0], mysecret[1], ..., mysecret[31]. Then do

mysecret[0] &= 248;

mysecret[31] &= 127;

mysecret[31] |= 64;

to create a 32-byte Curve25519 secret key mysecret[0], mysecret[1], ..., mysecret[31].

So all you need is 256bits and then modify a few bits. To get 256 bits, you can simply hash your password using a KDF such as Argon2. It makes it way harder to bruteforce, as you can select an iteration numbers and other parameters, chosen accordingly to match your security requirements.

Lou_is
  • 801
  • 1
  • 4
  • 14
  • If you use a weak hash instead of a KDF, and the attacker knows a ciphertext or a public key, then they can use them to brute-force the password to find the public+private keypair. – Macil Sep 25 '19 at 06:55
  • You're right, didn't think about it. Care to edit or post your own answer? – Lou_is Sep 25 '19 at 07:06