如何使用libsodium php使用salt加密/解密密码

What i am trying to get is

  • encrypt a password + salt with libsodium
  • store it to a database
  • read it and decrypt it (getting the plain password back for authentication)

I got a list of salts that i want to use to encrypt / decrypt my password. When i encrypt the password i get a hash back so that one seems to work but at decrypting i always get false as return value.

Am i using the wrong methods for encrypt / decrypt with libsodium or am i completely driving in the wrong direction?

My source for encrypt / decrypt:

function encrypt_libsodium($to_encrypt, $salt_to_use){
        if(!$data || !$salt_to_use){
            return null;
        }

        //get stored salt
        $this->key_ = substr(md5($this->pw_key[$salt_to_use].'_'), 0, $this->ks);

        //some libsodium specific stuff
        $out_len = \Sodium\CRYPTO_SIGN_SEEDBYTES;
        $ops_limit = \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE;
        $mem_limit =\Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE;

        //create hash using libsodium
        $hash = \Sodium\crypto_pwhash($out_len, $to_encrypt, $this->key_,$ops_limit, $mem_limit);
        return $hash;
    }

    function decrypt_libsodium($hash, $salt_to_use){
        if(!$hash || !$what){
            return null;
        }

        //get stored salt
        $this->key_ = substr(md5($this->pw_key[$salt_to_use].'_'), 0, $this->ks);

        //get verification hash
        $decrypted = \Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify($this->key_, $hash);
        return $decrypted;
    }

I appreciate any help!

regards Dom

If you dont need specifically use libsodium, with this function you should be able to store the data encrypted in the database and decrypt it.

define("ENCRYPT_METHOD", "AES-256-CBC");
define("SECRET_KEY","randomtextrandomtextforthesecretkey");
define("SECRET_IV", "randomtextforthesecretiv");
function encriptar($action, $string)
{
  $output = false;
  $key    = hash("sha256", SECRET_KEY);
  $iv     = substr(hash("sha256", SECRET_IV), 0, 16);

  if ($action == "encrypt")
  {
    $output = openssl_encrypt($string, ENCRYPT_METHOD, $key, 0, $iv);
    $output = base64_encode($output);
  }
  else if($action == "decrypt")
    {
        $output = base64_decode($string);
        $output = openssl_decrypt($output, ENCRYPT_METHOD, $key, 0, $iv);
    }
  return $output;
}

The output will be the data you will store/get to database.

Looks like you are trying to mix many unrelated things. CRYPTO_SIGN_SEEDBYTES is for signatures, which has nothing to do with password hashing, crypto_pwhash doesn't use the scrypt algorithm, so the CRYPTO_PWHASH_SCRYPTSALSA208SHA256_* constants don't apply, and I'm not sure what md5() does here. And you probably want to hash the password, not to encrypt it.

Anyway, the crypto_pwhash_str() function does everything you need. It creates a salt, hashes the password, and encodes the result (along with the salt, the algorithm and its parameters) as a string that you can directly store into the database:

$password = 'correct horse battery staple';
$h = \Sodium\crypto_pwhash_str($password,                                   
         \Sodium\CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
         \Sodium\CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);

$h is all you need to store in the database.

Then, to verify that what you have in the database is valid for a given password:

if (\Sodium\crypto_pwhash_str_verify($h, $password) === FALSE) {
    // wrong password!
}