示例#1
0
 /**
  * SharedMemory constructor
  *.
  * @param Key|null $cacheKey
  * @param AuthenticationKey|null $authKey
  * @param string $personalization
  */
 public function __construct(Key $cacheKey = null, AuthenticationKey $authKey = null, string $personalization = '')
 {
     if (!$cacheKey) {
         $state = State::instance();
         $cacheKey = $state->keyring['cache.hash_key'];
     }
     // We need a short hash key:
     $this->cacheKeyL = CryptoUtil::safeSubstr($cacheKey->getRawKeyMaterial(), 0, \Sodium\CRYPTO_SHORTHASH_KEYBYTES);
     $this->cacheKeyR = CryptoUtil::safeSubstr($cacheKey->getRawKeyMaterial(), \Sodium\CRYPTO_SHORTHASH_KEYBYTES, \Sodium\CRYPTO_SHORTHASH_KEYBYTES);
     if ($authKey) {
         $this->authKey = $authKey;
     }
     $this->personalization = $personalization;
 }
示例#2
0
 /**
  * Decrypt then verify a password
  * 
  * @param string $password          - The user-provided password
  * @param string $stored            - The encrypted password hash
  * @param EncryptionKey $secret_key  - The master key for all passwords
  * @return boolean
  */
 public static function verify(string $password, string $stored, EncryptionKey $secret_key) : bool
 {
     // First let's decrypt the hash
     $hash_str = Crypto::decrypt($stored, $secret_key);
     // Upon successful decryption, verify the password is correct
     $isArgon2 = \hash_equals(CryptoUtil::safeSubstr($hash_str, 0, 9), \Sodium\CRYPTO_PWHASH_STRPREFIX);
     $isScrypt = \hash_equals(CryptoUtil::safeSubstr($hash_str, 0, 3), \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX);
     if ($isArgon2) {
         return \Sodium\crypto_pwhash_str_verify($hash_str, $password);
     } elseif ($isScrypt) {
         return \Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify($hash_str, $password);
     }
     return false;
 }
示例#3
0
 /**
  * Unpack a message string into an array (assigned to variables via list()).
  *
  * Should return exactly 6 elements.
  * 
  * @param string $ciphertext
  * @return string[]
  * @throws InvalidMessage
  */
 public static function unpackMessageForDecryption(string $ciphertext) : array
 {
     $length = CryptoUtil::safeStrlen($ciphertext);
     // Fail fast on invalid messages
     if ($length < Halite::VERSION_TAG_LEN) {
         throw new InvalidMessage('Message is too short');
     }
     // The first 4 bytes are reserved for the version size
     $version = CryptoUtil::safeSubstr($ciphertext, 0, Halite::VERSION_TAG_LEN);
     $config = SymmetricConfig::getConfig($version, 'encrypt');
     if ($length < $config->SHORTEST_CIPHERTEXT_LENGTH) {
         throw new InvalidMessage('Message is too short');
     }
     // The salt is used for key splitting (via HKDF)
     $salt = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN, $config->HKDF_SALT_LEN);
     // This is the nonce (we authenticated it):
     $nonce = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN, \Sodium\CRYPTO_STREAM_NONCEBYTES);
     // This is the crypto_stream_xor()ed ciphertext
     $encrypted = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN + \Sodium\CRYPTO_STREAM_NONCEBYTES, $length - (Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN + \Sodium\CRYPTO_STREAM_NONCEBYTES + $config->MAC_SIZE));
     // $auth is the last 32 bytes
     $auth = CryptoUtil::safeSubstr($ciphertext, $length - $config->MAC_SIZE);
     // We don't need this anymore.
     \Sodium\memzero($ciphertext);
     // Now we return the pieces in a specific order:
     return [$version, $config, $salt, $nonce, $encrypted, $auth];
 }