/** * @param AlgInterface $alg * @param EncInterface $enc * @param string $content * @param string $public_or_secret_key * @return string */ public static function encrypt(AlgInterface $alg, EncInterface $enc, $content, $public_or_secret_key) { $protected_header = new Header(array('alg' => $alg->getAlg(), 'enc' => $enc->getEnc())); $aad_base64 = $protected_header->toString(); $cek = new ContentEncryptionKey(); $encrypted_cek = $alg->encrypt($cek->getCek(), $public_or_secret_key); list($iv, $cipher_text, $auth_tag) = $enc->encrypt($aad_base64, $cek, $content); return implode('.', [$aad_base64, Base64Url::encode($encrypted_cek), Base64Url::encode($iv), Base64Url::encode($cipher_text), Base64Url::encode($auth_tag)]); }
/** * @param string $aad_base64 * @param string $iv * @param string $cipher_text * @param ContentEncryptionKey $cek * @return string */ protected function createAuthenticationTag($aad_base64, $iv, $cipher_text, ContentEncryptionKey $cek) { // 64-Bit Big-Endian Representation of AAD Length $aad_length = Str::len($aad_base64); if (version_compare(PHP_VERSION, '5.6.3', '>=')) { $al_value = pack('J1', $aad_length); } else { $int32bit_max = 2147483647; $al_value = pack('N2', $aad_length / $int32bit_max * 8, $aad_length % $int32bit_max * 8); } // Concatenate the AAD, the Initialization Vector, the ciphertext, and the AL value. $concatenated_value = implode('', array($aad_base64, $iv, $cipher_text, $al_value)); // Compute the HMAC of the concatenated value above $hmac = hash_hmac($this->getHashAlgorithm(), $concatenated_value, $cek->getMacKey(), true); // Use the first half (128 bits) of the HMAC output M as the Authentication Tag output T. return Str::substr($hmac, 0, 16); }