/** * @param HiddenString $password * @return bool */ public function tryUnlockPassword(HiddenString $password) : bool { $state = State::instance(); return Password::verify($password->getString(), $this->installHash, $state->keyring['auth.password_key']); }
/** * Encrypt a message using the Halite encryption protocol * * (Encrypt then MAC -- xsalsa20 then keyed-Blake2b) * You don't need to worry about chosen-ciphertext attacks. * * @param HiddenString $plaintext * @param EncryptionKey $secretKey * @param mixed $encoding * @return string */ public static function encrypt(HiddenString $plaintext, EncryptionKey $secretKey, $encoding = Halite::ENCODE_BASE64URLSAFE) : string { $config = SymmetricConfig::getConfig(Halite::HALITE_VERSION, 'encrypt'); // Generate a nonce and HKDF salt: $nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES); $salt = \Sodium\randombytes_buf($config->HKDF_SALT_LEN); /* Split our key into two keys: One for encryption, the other for authentication. By using separate keys, we can reasonably dismiss likely cross-protocol attacks. This uses salted HKDF to split the keys, which is why we need the salt in the first place. */ list($encKey, $authKey) = self::splitKeys($secretKey, $salt, $config); // Encrypt our message with the encryption key: $encrypted = \Sodium\crypto_stream_xor($plaintext->getString(), $nonce, $encKey); \Sodium\memzero($encKey); // Calculate an authentication tag: $auth = self::calculateMAC(Halite::HALITE_VERSION . $salt . $nonce . $encrypted, $authKey, $config); \Sodium\memzero($authKey); $message = Halite::HALITE_VERSION . $salt . $nonce . $encrypted . $auth; // Wipe every superfluous piece of data from memory \Sodium\memzero($nonce); \Sodium\memzero($salt); \Sodium\memzero($encrypted); \Sodium\memzero($auth); $encoder = Halite::chooseEncoder($encoding); if ($encoder) { return $encoder($message); } return $message; }
/** * You probably should not be using this directly. * * @param HiddenString $keyMaterial - The actual key data */ public function __construct(HiddenString $keyMaterial) { $this->keyMaterial = Util::safeStrcpy($keyMaterial->getString()); }
/** * Encrypt a message with a target users' public key * * @param HiddenString $plaintext Message to encrypt * @param EncryptionPublicKey $publicKey Public encryption key * @param mixed $encoding Which encoding scheme to use? * @return string Ciphertext * @throws CannotPerformOperation * @throws InvalidKey */ public static function seal(HiddenString $plaintext, EncryptionPublicKey $publicKey, $encoding = Halite::ENCODE_BASE64URLSAFE) : string { if (!$publicKey instanceof EncryptionPublicKey) { throw new InvalidKey('Argument 2: Expected an instance of EncryptionPublicKey'); } $sealed = \Sodium\crypto_box_seal($plaintext->getString(), $publicKey->getRawKeyMaterial()); $encoder = Halite::chooseEncoder($encoding); if ($encoder) { return $encoder($sealed); } return $sealed; }