2

I know a salt isn't secure data that needs to be encrypted in the dB, but as its access should be controlled, is it considered safe to save it as a session variable at login for use later on different pages? Or should it be looked up in the dB with every request. My reasoning is less calls to the dB.

This is a home project password manager website, with a user base of one, but written as if it was for multiple users.

EDIT: The login is handled via php utilising password_hash($password, PASSWORD_DEFAULT), which I believe handles its own salting, if I am understanding the manual correctly. The salting in question is for the users password database/manager, which uses a separate password for key verification generation to encrypt/decrypt the passwords. I thought I was using a single master salt on a per user basis, but it turns out that was incorrect.

Original Code:

function sodiumKeygen($password){
// create a 32 character secret key from the supplied password

  $key =  hash('tiger128,4', $password,false);

  return($key);
}

function encryptPassword($pass,$key){
/* encrypt $pass using the sodium crypto library
   return the encrypted value as base64 encoded $cipher
   to store nicesly in DB*/

  // nonce to append to cipher
  $nonce = random_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES );
  $cipher = $nonce . sodium_crypto_secretbox($pass, $nonce, $key);

  // destroy $pass and $key once no longer needed
  sodium_memzero($pass);
  sodium_memzero($key);

  return($cipher);
}

And after reading the comments to the question made the changes:

function generateSalt($length=SODIUM_CRYPTO_PWHASH_SALTBYTES){
  $salt = base64_encode(random_bytes($length));
  return($salt);
}

function sodiumKeygen2($password, $saltBase64){
// create a 32 bit secret key from the supplied password and user salt
  $length = SODIUM_CRYPTO_SECRETBOX_KEYBYTES;

  // ops and mem limit work factor. 100 pw takes 5min at sensitive
  // mode. set ops and mem to same level.
  $opslimitLo = SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE;
  $opslimitMid = SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE;
  $opslimitHi = SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE;
  $memlimitLo = SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE;
  $memlimitMid = SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE;
  $memlimitHi = SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE;

  $algo = SODIUM_CRYPTO_PWHASH_ALG_DEFAULT;
  $id = SODIUM_BASE64_VARIANT_URLSAFE;
  $salt = base64_decode($saltBase64);

  $key =  sodium_crypto_pwhash($length, $password, $salt, $opslimitMid, $memlimitMid, $algo);

  return($key);
}

function sodiumEncryptPassword($pass,$key){
/* encrypt $pass using the sodium crypto library
   return the encrypted value as base64 encoded $cipher
   to store nicesly in DB*/
  
  $id = SODIUM_BASE64_VARIANT_URLSAFE;
  
  // nonce to append to cipher
  $nonce = random_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES );
  
  // cipher is converted to base64 for DB storage
  $cipher = sodium_bin2base64($nonce . sodium_crypto_secretbox($pass, $nonce, $key), $id);
  
  // destroy $pass and $key once no longer needed
  sodium_memzero($pass);
  sodium_memzero($key);

  return($cipher);
}

The salt generated by the function generateSalt() is now unique to each password saved and stored along side it. It now makes sense to retrieve it alongside the password in the same query. There is no requirement to store it in a session variable so this question is now moot for my application.

12
  • 1
    If you don't mind me asking, why is it written for multiple users if it will only be yourself? Or are you planning for the future? Commented Jun 12 at 9:46
  • 4
    The better question is "why is the salt required so many times in a single session?" I'm thinking your session management structure is broken.
    – schroeder
    Commented Jun 12 at 9:50
  • 2
    You would need the salt only if you are authenticating multiple times per session, so perhaps you are using the password multiple times per session. That should not be happening.
    – ThoriumBR
    Commented Jun 12 at 10:03
  • 1
    @ThoriumBR and even then, in this case, the salt would be retrieved together with the password hash and there would be no reason to keep it in session
    – Najkin
    Commented Jun 12 at 10:45
  • 1
    @security_paranoid, for fun mainly, and in case my wife wants to use some of the features.
    – Èl Sea
    Commented Jun 12 at 12:58

1 Answer 1

3

Salt helps defend against attacks that use precomputed tables (source)

You can store it in the session data ... but there is really no need to do so. It should be stored along side the hashed password as its only reason for existing is to slow down attackers.

In terms of session, you shouldn't be hitting password_hash algorithm more than once per session. It is generally considered best practice to auth once and then generate a UUID as a session token. This token should be stored in a cookie and used as proof of login from that point on ... or refresh a TTL each time a user takes an action on the page. Sessions expiring is a whole diff question.

The only other time you should be hitting password_hash function is in the event that a user wants to change auth info like change their password / email address that the password reset goes to / 2fa / sshkeys etc.

TLDR: should you store the salt in the session ... no, but only because there is no reason to do so.

2
  • It should also be noted that if you use the salt as the session ID ... it wouldnt change which would give an attacker perm access to the account as the session ID would remain the same once stolen. But again, this should be asked in a diff question. Commented Jun 13 at 2:16
  • The way you explain it make sense. My login session was handled separately, and the only time password_hash was used after this was to verify the password manager password (which is separate to the login password) before generating keys for any functions that involve encrypting or decrypting. As a point of interest it took less that 1 second to re-encrypt 100 passwords with opslimit/memlimit at interactive mode, 10 seconds at moderate, and 5 mins at secure.
    – Èl Sea
    Commented Jun 13 at 4:23

You must log in to answer this question.

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