You are here

class LockrAes128CtrSha256KeyWrapper in Lockr 7.2

Same name and namespace in other branches
  1. 7.3 vendor/lockr/lockr/src/KeyWrapper/LockrAes128CtrSha256KeyWrapper.php \Lockr\KeyWrapper\LockrAes128CtrSha256KeyWrapper

Hierarchy

Expanded class hierarchy of LockrAes128CtrSha256KeyWrapper

File

vendor/lockr/lockr-client/src/KeyWrapper/LockrAes128CtrSha256KeyWrapper.php, line 6

Namespace

Lockr\KeyWrapper
View source
class LockrAes128CtrSha256KeyWrapper implements KeyWrapperInterface {
  const PREFIX = 'aes-128-ctr-sha256';
  const METHOD = 'aes-128-ctr';
  const HASH_BYTES = 44;

  /**
   * {@inheritdoc}
   */
  public static function enabled() {
    return function_exists('openssl_encrypt');
  }

  /**
   * {@inheritdoc}
   */
  public static function encrypt($plaintext) {
    $key = openssl_random_pseudo_bytes(32);
    $iv_len = openssl_cipher_iv_length(self::METHOD);
    $iv = openssl_random_pseudo_bytes($iv_len);
    $ciphertext = openssl_encrypt($plaintext, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);
    $hmac_key = openssl_random_pseudo_bytes(32);
    $hmac = self::hmac($ciphertext, $hmac_key);
    return array(
      'ciphertext' => base64_encode($hmac) . base64_encode($ciphertext),
      'encoded' => self::encode($key, $iv, $hmac_key),
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function decrypt($ciphertext, $encoded) {
    $parts = self::decode($encoded);
    if (!$parts) {
      return false;
    }
    list($key, $iv, $hmac_key) = $parts;
    $hmac = base64_decode(substr($ciphertext, 0, self::HASH_BYTES));
    $ciphertext = base64_decode(substr($ciphertext, self::HASH_BYTES));
    if (!self::hashEquals($hmac, self::hmac($ciphertext, $hmac_key))) {
      return false;
    }
    $plaintext = openssl_decrypt($ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);
    if ($plaintext === false) {
      return false;
    }
    return $plaintext;
  }

  /**
   * {@inheritdoc}
   */
  public static function reencrypt($plaintext, $encoded) {
    $parts = self::decode($encoded);
    if (!$parts) {
      return false;
    }
    list($key, $iv, $hmac_key) = $parts;
    $ciphertext = openssl_encrypt($plaintext, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);
    $hmac = self::hmac($ciphertext, $hmac_key);
    return array(
      'ciphertext' => base64_encode($hmac) . base64_encode($ciphertext),
      'encoded' => $encoded,
    );
  }
  protected static function hmac($data, $key) {
    return hash_hmac('sha256', $data, $key, true);
  }
  protected static function hashEquals($left, $right) {
    if (function_exists('hash_equals')) {
      return hash_equals($left, $right);
    }
    $ret = 0;
    if (strlen($left) !== strlen($right)) {
      $right = $left;
      $ret = 1;
    }
    $res = $left ^ $right;
    for ($i = strlen($res) - 1; $i >= 0; --$i) {
      $ret |= ord($res[$i]);
    }
    return !$ret;
  }
  protected static function encode($key, $iv, $hmac_key) {
    $parts = array(
      self::PREFIX,
      base64_encode($key),
      base64_encode($iv),
      base64_encode($hmac_key),
    );
    return implode('$', $parts);
  }
  protected static function decode($encoded) {
    $parts = explode('$', $encoded, 4);
    if (!$parts || count($parts) != 4) {
      return false;
    }
    list($prefix, $key, $iv, $hmac_key) = $parts;
    if ($prefix !== self::PREFIX) {
      return false;
    }
    return array(
      base64_decode($key),
      base64_decode($iv),
      base64_decode($hmac_key),
    );
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LockrAes128CtrSha256KeyWrapper::decode protected static function
LockrAes128CtrSha256KeyWrapper::decrypt public static function Decrypt the given ciphertext using encoded. Overrides KeyWrapperInterface::decrypt
LockrAes128CtrSha256KeyWrapper::enabled public static function Overrides KeyWrapperInterface::enabled
LockrAes128CtrSha256KeyWrapper::encode protected static function
LockrAes128CtrSha256KeyWrapper::encrypt public static function Encrypt the given plaintext. Overrides KeyWrapperInterface::encrypt
LockrAes128CtrSha256KeyWrapper::hashEquals protected static function
LockrAes128CtrSha256KeyWrapper::HASH_BYTES constant
LockrAes128CtrSha256KeyWrapper::hmac protected static function
LockrAes128CtrSha256KeyWrapper::METHOD constant
LockrAes128CtrSha256KeyWrapper::PREFIX constant
LockrAes128CtrSha256KeyWrapper::reencrypt public static function Encrypt the given plaintext using the same initial state as defined by encoded. Overrides KeyWrapperInterface::reencrypt