Beispiel #1
0
 /**
  * Encrypt a message using the Halite encryption protocol
  * 
  * @param string $plaintext
  * @param Key $secretKey
  * @param boolean $raw Don't hex encode the output?
  * @return string
  */
 public static function encrypt($plaintext, Contract\CryptoKeyInterface $secretKey, $raw = false)
 {
     if ($secretKey->isAsymmetricKey()) {
         throw new CryptoAlert\InvalidKey('Expected a symmetric key, not an asymmetric key');
     }
     if (!$secretKey->isEncryptionKey()) {
         throw new CryptoAlert\InvalidKey('Encryption key expected');
     }
     $nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
     $salt = \Sodium\randombytes_buf(Config::HKDF_SALT_LEN);
     list($eKey, $aKey) = self::splitKeys($secretKey, $salt);
     $xored = \Sodium\crypto_stream_xor($plaintext, $nonce, $eKey);
     $auth = self::calculateMAC(Config::HALITE_VERSION . $salt . $nonce . $xored, $aKey);
     \Sodium\memzero($eKey);
     \Sodium\memzero($aKey);
     if (!$raw) {
         return \Sodium\bin2hex(Config::HALITE_VERSION . $salt . $nonce . $xored . $auth);
     }
     return Config::HALITE_VERSION . $salt . $nonce . $xored . $auth;
 }
Beispiel #2
0
 /**
  * Unseal a (file handle)
  * 
  * @param $input
  * @param $output
  * @param \ParagonIE\Halite\Contract\CryptoKeyInterface $secretkey
  */
 public static function unsealResource($input, $output, \ParagonIE\Halite\Contract\CryptoKeyInterface $secretkey)
 {
     // Input validation
     if (!\is_resource($input)) {
         throw new \ParagonIE\Halite\Alerts\InvalidType('Expected input handle to be a resource');
     }
     if (!\is_resource($output)) {
         throw new \ParagonIE\Halite\Alerts\InvalidType('Expected output handle to be a resource');
     }
     if (!$secretkey->isSecretKey()) {
         throw new CryptoAlert\InvalidKey('Expected a secret key');
     }
     if (!$secretkey->isAsymmetricKey()) {
         throw new CryptoAlert\InvalidKey('Expected a key intended for asymmetric-key cryptography');
     }
     $secret_key = $secretkey->get();
     $public_key = \Sodium\crypto_box_publickey_from_secretkey($secret_key);
     // Parse the header, ensuring we get 4 bytes
     $header = self::readBytes($input, Halite::VERSION_TAG_LEN);
     // Load the config
     $config = self::getConfig($header, 'seal');
     // Let's grab the public key and salt
     $eph_public = self::readBytes($input, $config['PUBLICKEY_BYTES']);
     $hkdfsalt = self::readBytes($input, $config['HKDF_SALT_LEN']);
     $nonce = \Sodium\crypto_generichash($eph_public . $public_key, null, \Sodium\CRYPTO_STREAM_NONCEBYTES);
     $ephemeral = new Key($eph_public, true, false, true);
     $key = Asymmetric::getSharedSecret($secretkey, $ephemeral, true);
     list($encKey, $authKey) = self::splitKeys($key, $hkdfsalt);
     // We no longer need the original key after we split it
     unset($key);
     $mac = \hash_init('sha256', HASH_HMAC, $authKey);
     \hash_update($mac, $header);
     \hash_update($mac, $eph_public);
     \hash_update($mac, $hkdfsalt);
     // This will throw an exception if it fails.
     $old_macs = self::streamVerify($input, \hash_copy($mac), $config);
     $ret = self::streamDecrypt($input, $output, new Key($encKey), $nonce, $mac, $config, $old_macs);
     unset($encKey);
     unset($authKey);
     unset($nonce);
     unset($mac);
     unset($config);
     unset($old_macs);
     return $ret;
 }