Skip to content

Instantly share code, notes, and snippets.

@paragonie-scott
Last active February 7, 2019 03:28
Show Gist options
  • Save paragonie-scott/3d06442e39d27e9295b2826ac84860f3 to your computer and use it in GitHub Desktop.
Save paragonie-scott/3d06442e39d27e9295b2826ac84860f3 to your computer and use it in GitHub Desktop.
Password-Derived CipherSweet Key Provider
<?php
namespace OpenEMR\OpenEMR\KeyProvider;
use ParagonIE\CipherSweet\Backend\Key\SymmetricKey;
use ParagonIE\CipherSweet\Backend\FIPSCrypto;
use ParagonIE\CipherSweet\Backend\ModernCrypto;
use ParagonIE\CipherSweet\Contract\BackendInterface;
use ParagonIE\CipherSweet\Contract\KeyProviderInterface;
use ParagonIE\CipherSweet\Exception\CryptoOperationException;
use ParagonIE\CipherSweet\Util;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\ConstantTime\Binary;
use ParagonIE\ConstantTime\Hex;
/**
* Class StringProvider
* @package OpenEMR\OpenEMR\KeyProvider
*/
class PasswordDerivedKeyProvider implements KeyProviderInterface
{
/**
* @var BackendInterface $backend
*/
private $backend;
/**
* @var string $rootSymmetricKey
*/
private $rootSymmetricKey;
/**
* StringProvider constructor.
*
* @param BackendInterface $backend
* @param string $password
* @param string $salt
*
* @throws CryptoOperationException
*/
public function __construct(BackendInterface $backend, $password = '', $salt = '')
{
$this->backend = $backend;
if (empty($password) || empty($salt)) {
throw new CryptoOperationException("Password and salt must be provided.");
}
switch (\get_class($this->backend)) {
case FIPSCrypto::class:
$this->rootSymmetricKey = \hash_pbkdf2('sha384', $password, $salt, 100000, 32, true);
break;
case ModernCrypto::class:
$this->rootSymmetricKey = \sodium_crypto_pwhash(
32,
$password,
$salt,
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
break;
default:
throw new CryptoOperationException("Unknown backend");
}
}
/**
* Attempt to wipe memory.
*
* @throws \SodiumException
*/
public function __destruct()
{
Util::memzero($this->rootSymmetricKey);
}
/**
* @return BackendInterface
*/
public function getBackend()
{
return $this->backend;
}
/**
* @return SymmetricKey
*/
public function getSymmetricKey()
{
return new SymmetricKey($this->backend, $this->rootSymmetricKey);
}
/**
* @return array
*/
public function __debugInfo()
{
return [];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment