function AESDecrypt($ciphertext, $key, $IV) { $aes = new Crypt_AES(CRYPT_MODE_ECB); $aes->setKey(characet($key)); $aes->setIV(characet($IV)); return $aes->decrypt(hex2bin($ciphertext)); }
protected function initAes($key, $iv, $keySize) { $this->aes = new \Crypt_AES(); $this->aes->setKeyLength($keySize); $this->aesKey = $key; $this->aesIV = $iv; $this->aes->setKey($this->aesKey); $this->aes->setIV($this->aesIV); }
/** * Decrypt the provided data using AES cryptography with the provided key and IV * * @param string $data Data to decrypt * @param string $key Cipher key used to encrypt the data * @param string $iv IV used to encrypt the data * @param bool $base64Encoded Is the provided data Base64 encoded (defaults to true) * @return string Unencrypted data */ public function decryptAES($data, $key, $iv, $base64Encoded = true) { $data = $base64Encoded ? base64_decode($data) : $data; $cipher = new \Crypt_AES(); $cipher->setKey($key); $cipher->setIV($iv); $cipher->disablePadding(); $decrypted = rtrim($cipher->decrypt($data)); return $decrypted; }
/** * @dataProvider continuousBufferCombos */ public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key) { $aes = new Crypt_AES(constant($mode)); $aes->enableContinuousBuffer(); $aes->setIV($iv); $aes->setKey($key); $actual = ''; for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) { $actual .= $aes->decrypt($aes->encrypt($plaintext[$i])); } $this->assertEquals($plaintext, $actual); }
public static function decrypt($secret, $password, ApiKeyEncryptionOptions $options) { $decodedSecret = self::base64url_decode($secret); $salt = self::base64url_decode($options->getEncryptionKeySalt()); $iterations = $options->getEncryptionKeyIterations(); $keyLengthBits = $options->getEncryptionKeySize(); $iv = substr($decodedSecret, 0, 16); $aes = new \Crypt_AES(); $aes->setPassword($password, 'pbkdf2', 'sha1', $salt, $iterations, $keyLengthBits / 8); $aes->setKeyLength($keyLengthBits); $aes->setIV($iv); return $aes->decrypt(substr($decodedSecret, 16)); }
/** * Checks whether a user has the right to enter on the platform or not * @param string The username, as provided in form * @param string The cleartext password, as provided in form * @param string The WS URL, as provided at the beginning of this script */ function loginWSAuthenticate($username, $password, $wsUrl) { // check params if (empty($username) or empty($password) or empty($wsUrl)) { return false; } // Create new SOAP client instance $client = new SoapClient($wsUrl); if (!$client) { return false; } // Include phpseclib methods, because of a bug with AES/CFB in mcrypt include_once api_get_path(LIBRARY_PATH) . 'phpseclib/Crypt/AES.php'; // Define all elements necessary to the encryption $key = '-+*%$({[]})$%*+-'; // Complete password con PKCS7-specific padding $blockSize = 16; $padding = $blockSize - strlen($password) % $blockSize; $password .= str_repeat(chr($padding), $padding); $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB); $cipher->setKeyLength(128); $cipher->setKey($key); $cipher->setIV($key); $cipheredPass = $cipher->encrypt($password); // Mcrypt call left for documentation purposes - broken, see https://bugs.php.net/bug.php?id=51146 //$cipheredPass = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_CFB, $key); // Following lines present for debug purposes only /* $arr = preg_split('//', $cipheredPass, -1, PREG_SPLIT_NO_EMPTY); foreach ($arr as $char) { error_log(ord($char)); } */ // Change to base64 to avoid communication alteration $passCrypted = base64_encode($cipheredPass); // The call to the webservice will change depending on your definition try { $response = $client->validateUser(array('user' => $username, 'pass' => $passCrypted, 'system' => 'chamilo')); } catch (SoapFault $fault) { error_log('Caught something'); if ($fault->faultstring != 'Could not connect to host') { error_log('Not a connection problem'); throw $fault; } else { error_log('Could not connect to WS host'); } return 0; } return $response->validateUserResult; }
/** * Process the launchkey option to prepare for usage within the plugin. The option will have encrypted attributes * decrypted as well as set default values for any missing or unset attributes. * * @since 1.0.0 * * @param $input * * @return array */ public function post_get_option_filter($input) { // Define the defaults for attributes $defaults = static::get_defaults(); // If the input is empty (null) set it to an empty array $input ?: array(); // Merge the input array over the defaults array to set any know data to the response $output = array_merge($defaults, $input); // If the secret key attribute is not empty, decrypt it if (!empty($input[LaunchKey_WP_Options::OPTION_SECRET_KEY])) { $key = md5($input[LaunchKey_WP_Options::OPTION_SECRET_KEY]); if (empty($this->cache[$key])) { /** * Use the rocket key as the IV. If null, use the static value. * @link https://docs.launchkey.com/glossary.html#term-iv */ $iv = empty($output[LaunchKey_WP_Options::OPTION_ROCKET_KEY]) ? static::STATIC_IV : $output[LaunchKey_WP_Options::OPTION_ROCKET_KEY]; $this->crypt_aes->setIV($iv); /** * Decrypt the Base64 decoded string and set it as the output value * @link https://docs.launchkey.com/glossary.html#term-base64 */ $this->cache[$key] = $this->crypt_aes->decrypt(base64_decode($input[LaunchKey_WP_Options::OPTION_SECRET_KEY])); } $output[LaunchKey_WP_Options::OPTION_SECRET_KEY] = $this->cache[$key]; } // If the private key attribute is not empty, decrypt it if (!empty($input[LaunchKey_WP_Options::OPTION_PRIVATE_KEY])) { $key = md5($input[LaunchKey_WP_Options::OPTION_PRIVATE_KEY]); if (empty($this->cache[$key])) { /** * Use the decrypted secret key as the IV. If null, use the static value. * @link https://docs.launchkey.com/glossary.html#term-iv */ $iv = empty($output[LaunchKey_WP_Options::OPTION_SECRET_KEY]) ? static::STATIC_IV : $output[LaunchKey_WP_Options::OPTION_SECRET_KEY]; $this->crypt_aes->setIV($iv); /** * Decrypt the Base64 decoded string and set it as the output value * @link https://docs.launchkey.com/glossary.html#term-base64 * * We are suppressing errors as */ $this->cache[$key] = @$this->crypt_aes->decrypt(base64_decode($input[LaunchKey_WP_Options::OPTION_PRIVATE_KEY])); } $output[LaunchKey_WP_Options::OPTION_PRIVATE_KEY] = $this->cache[$key]; } return $output; }
/** * Initializes AES instance using either provided $options or session values * @param array $options Array of options, containing 'key' and 'iv' values * @return mixed|void * @throws Exception */ public function initSymmetric($options = array()) { if (empty($options) && Session::has('aes_key') && Session::has('aes_iv')) { $options = array('key' => Session::get('aes_key'), 'iv' => Session::get('aes_iv')); } if (!(isset($options['key']) && isset($options['iv']))) { \Log::error("Either key or iv not set"); throw new \Exception("Either key or iv not set"); } Session::put('aes_key', $options['key']); Session::put('aes_iv', $options['iv']); $aes = new \Crypt_AES(CRYPT_AES_MODE_CBC); $aes->setKeyLength(256); $aes->setKey(Base64::UrlDecode($options['key'])); $aes->setIV(Base64::UrlDecode($options['iv'])); $aes->enablePadding(); $this->aes = $aes; $this->isAesInitialized = true; }
static function ExtractDataPacket($data, $key, $options = array()) { $data = (string) $data; if (!isset($options["mode"])) { $options["mode"] = "ECB"; } if ($options["mode"] != "ECB" && (!isset($options["iv"]) || $options["iv"] == "")) { return false; } if (isset($options["key2"])) { $options2 = $options; if (isset($options["iv2"])) { $options["iv"] = $options["iv2"]; } else { unset($options["iv"]); } if (self::IsMcryptAvailable()) { $data = self::McryptDecrypt($data, $options["key2"], $options); } else { if (class_exists("Crypt_AES")) { $aes = new Crypt_AES($options["mode"] == "CBC" ? CRYPT_AES_MODE_CBC : CRYPT_AES_MODE_ECB); $aes->setKey($options["key2"]); if (isset($options["iv"])) { $aes->setIV($options["iv"]); } $aes->disablePadding(); $data = $aes->decrypt($data); } else { return false; } } $data = substr($data, 1) . substr($data, 0, 1); $options = $options2; } if (self::IsMcryptAvailable()) { $data = self::McryptDecrypt($data, $key, $options); } else { if (class_exists("Crypt_AES")) { $aes = new Crypt_AES($options["mode"] == "CBC" ? CRYPT_AES_MODE_CBC : CRYPT_AES_MODE_ECB); $aes->setKey($key); if (isset($options["iv"])) { $aes->setIV($options["iv"]); } $aes->disablePadding(); $data = $aes->decrypt($data); } else { return false; } } if ($data === false) { return false; } $pos = strpos($data, "\n"); if ($pos === false) { return false; } $data = substr($data, $pos + 1); $pos = strpos($data, "\n"); if ($pos === false) { return false; } $check = substr($data, 0, $pos); $data = substr($data, $pos + 1); $pos = strrpos($data, "\n"); if ($pos === false) { return false; } $data = substr($data, 0, $pos); if (!isset($options["lightweight"]) || !$options["lightweight"]) { if ($check !== strtolower(sha1($data))) { return false; } } else { if ($check !== strtolower(dechex(crc32($data)))) { return false; } } return $data; }
function random($len) { if (CRYPT_IS_WINDOWS) { if (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) { return openssl_random_pseudo_bytes($len); } // Looks like mcrypt_create_iv with MCRYPT_DEV_RANDOM is still // unreliable on 5.3.6: // https://bugs.php.net/bug.php?id=52523 if (function_exists('mcrypt_create_iv') && version_compare(PHP_VERSION, '5.3.7', '>=')) { return mcrypt_create_iv($len); } } else { if (function_exists('openssl_random_pseudo_bytes')) { return openssl_random_pseudo_bytes($len); } static $fp = null; if ($fp == null) { $fp = @fopen('/dev/urandom', 'rb'); } if ($fp) { return fread($fp, $len); } if (function_exists('mcrypt_create_iv')) { return mcrypt_create_iv($len, MCRYPT_DEV_URANDOM); } } $seed = session_id() . microtime() . getmypid(); $key = pack('H*', sha1($seed . 'A')); $iv = pack('H*', sha1($seed . 'C')); $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR); $crypto->setKey($key); $crypto->setIV($iv); $crypto->enableContinuousBuffer(); //Sliding iv. $start = mt_rand(5, PHP_INT_MAX); $output = ''; for ($i = $start; strlen($output) < $len; $i++) { $output .= $crypto->encrypt($i); } return substr($output, 0, $len); }
private function _decrypt_chunk($cipher_text, $last = false) { //Compute MAC on the ciphertext if ($this->compute_mac) { $this->_mac_chunk($cipher_text, $last); } //Perform decryption $aes = new \Crypt_AES(); $aes->setKey($this->key); $aes->setIV($this->next_iv); //if this is not the last chunk, we will need to reconstruct the //encrypted padding block if (!$last) { $dummy_iv = substr($cipher_text, -16); $dummy_plain = FileEncryptor::pack('C*', array_pad(array(), 16, 16)); $dummy_aes = new \Crypt_AES(); $dummy_aes->setKey($this->key); $dummy_aes->setIV($dummy_iv); $dummy_cipher = $dummy_aes->encrypt($dummy_plain); //$dummy_cipher itself has a dummy block which needs to be removed $dummy_block = substr($dummy_cipher, 0, -16); $cipher_text = $cipher_text . $dummy_block; $this->next_iv = $dummy_iv; } $plain_text = $aes->decrypt($cipher_text); return $plain_text; }
function SendEncryptedResponse($message) { $aes = new Crypt_AES(CRYPT_AES_MODE_CBC); $aes->setKeyLength(256); $aes->setKey(Base64UrlDecode($_SESSION['key'])); $aes->setIV(Base64UrlDecode($_SESSION['iv'])); $aes->enablePadding(); // This is PKCS echo Base64UrlEncode($aes->encrypt($message)); exit; }
<?php // // Copyright (c) 2011 Scott Clayton // // This file is part of the C# to PHP Encryption Library. // // The C# to PHP Encryption Library is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The C# to PHP Encryption Library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with the C# to PHP Encryption Library. If not, see <http://www.gnu.org/licenses/>. // include 'Crypt/AES.php'; $aes = new Crypt_AES(); $aes->setKey('abcdefghijklmnopabcdefghijklmnop'); $aes->setIV('abcdefghijklmnop'); $aes->setKeyLength(256); echo base64_encode("abcdefghijklmnopabcdefghijklmnop") . "<BR>"; echo base64_encode("abcdefghijklmnop") . "<BR>"; $plaintext = 'llamas are super cool!'; echo base64_encode($aes->encrypt($plaintext)) . "<BR>"; echo $aes->decrypt($aes->encrypt($plaintext));
public function login_get() { cacheHeaders(false); $this->load->Model('Vip'); $this->load->Model('User'); $username = $this->get('username'); $password = $this->get('password'); $flavour = $this->get('flavour'); $token = $this->get('token'); $socialnetwork = $this->get('socialnetwork'); $newsletter = $this->get('newsletter'); if (!$flavour) { $flavour = 'yousee'; } if (!$password) { $password = $this->input->server('HTTP_X_PASSWORD'); } // if token is set and socialnetwork is not // we assume old school token if ($token && !$socialnetwork) { $this->load->library('encrypt'); $decrypted = $this->encrypt->decode(base64_decode($token)); if ($decrypted) { $foo = explode('||||', $decrypted); if (is_array($foo) && count($foo) == 2) { $username = $foo[0]; $password = $foo[1]; } } } $apikey = $this->rest->key; $useencryption = !empty($this->sharedsecrets[$apikey]['key']) && $this->get('enc'); if ($useencryption) { $enctype = $this->sharedsecrets[$apikey]['type']; if ($enctype == 'ios') { $password = $this->input->server('HTTP_X_PASSWORD'); $password = @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->sharedsecrets[$apikey]['key'], base64_decode($password), MCRYPT_MODE_CBC); $password = preg_replace('/[\\x00-\\x1F\\x7F]/', '', $password); } else { if ($enctype == 'android-blockbuster') { $password = $this->input->server('HTTP_X_PASSWORD'); $cipher = new Crypt_AES(); $cipher->setKey($this->sharedsecrets[$apikey]['key']); $cipher->setIV($this->sharedsecrets[$apikey]['iv']); $password = $cipher->decrypt(base64_decode($password)); } } } $presentableError = null; if ($flavour == 'yousee') { $session_id = Facades\YSPRO::login($username, $password); if ($session_id) { $domain = 'xmpp.yousee.tv'; $userinfo = Facades\YSPRO::getUserInfo($session_id); if ($this->get('flavour') == 'yousee' && !$userinfo->customerNumber) { // only do this for new apps // WAT? // we don't want the old school users with customer numbers $allowLogin = false; $allowLogin = $isVip = $this->Vip->hasAccess($userinfo->userId, Vip::TVWEBLARGE) || $this->Vip->hasAccess($userinfo->userId, Vip::ARCHIVE) || $this->Vip->hasAccess($userinfo->userId, Vip::TVWEBSMALL) || $this->Vip->hasAccess($userinfo->userId, Vip::MOVIE) || $this->Vip->hasAccess($userinfo->userId, Vip::HBO) || $this->Vip->hasAccess($userinfo->userId, Vip::CMORE) || $this->Vip->hasAccess($userinfo->userId, Vip::YOUBIO); $cacheInstance = new \OdpCaching\Memcache(\OdpConfig\Config::getInstance()->getMemcacheServerpool()); $ysproInstance = new \OdpYspro\Yspro($cacheInstance); if (!$allowLogin) { // oh boy - we also need to check if the customer is a YouSee mobile customer // provisioned through YSPro $youseeMobile = new \OdpPermissions\YouSeeMobile($cacheInstance, $ysproInstance, $userinfo); $allowLogin = $youseeMobile->getPermission()->permission; } if (!$allowLogin) { // Play music users must be allowed to login $umapEngagement = $ysproInstance->getUmapEngagementForUserId($userinfo->userId); $allowLogin = !empty($umapEngagement['MSISDN']); } if (!$allowLogin) { // DkTv users must be allowed to login $allowLogin = with(new \OdpPermissions\DkTv($cacheInstance, $ysproInstance, $userinfo))->canLogin(); } if (!$allowLogin) { return $this->returnRestError(1052, 'Login does not grant access to app', 'Du har forsøgt at logge ind med et login uden tilknyttede YouSee produkter. Benyt i stedet dit YouSee Login, som du finder på yousee.dk under "Mit YouSee".', 400, false, true, $userinfo); } } } else { $presentableError = 'Du har indtastet forkert brugernavn eller adgangskode'; } } else { if ($flavour == 'tdc') { $session_id = Facades\CoreID::login($username, $password); if ($session_id) { $domain = 'xmpp.tdc.dk'; $userinfo = Facades\CoreID::getUserInfo($session_id); } else { $tdcError = Facades\CoreID::getLastTdcError(); if ($tdcError) { if ($tdcError = 1) { $presentableError = 'Du har indtastet forkert brugernavn eller adgangskode'; } else { if ($tdcError = 2) { $presentableError = 'Dit login er spærret i 12 timer, da du har forsøgt at logge på med forkert adgangskode 10 gange'; } else { if ($tdcError = 4) { $presentableError = 'Du skal skifte dit brugernavn på play.tdc.dk'; } else { $presentableError = 'Du har indtastet forkert brugernavn eller adgangskode'; } } } } } } else { if ($flavour == 'blockbuster') { if ($token && $socialnetwork) { try { $blockbusterFacebook = new \OdpYspro\BlockbusterFacebook(); $facebookUserId = $blockbusterFacebook->getUserId($token); } catch (\OdpYspro\CannotConnectToFacebookOpenGraphException $e) { return $this->returnRestError(1042, 'Cannot connect to Facebook API', null, 400); } catch (\OdpYspro\CannotDecodeAccessTokenException $e) { return $this->returnRestError(1043, 'Cannot decode facebook token', null, 400); } catch (\OdpYspro\FacebookAccessTokenIsExpiredException $e) { return $this->returnRestError(1044, 'Access token has expired', null, 400); } catch (\OdpYspro\CannotReadEmailAddressException $e) { return $this->returnRestError(1048, 'Cannot read email address from Facebook token', null, 404); } $session_id = Facades\BlockBusterLogin::facebookLogin($facebookUserId, $token); if (!$session_id) { $status = \Facades\BlockBusterLogin::createFacebookLogin($token); if (!$status) { $lastError = Facades\BlockBusterLogin::getLastError(); if ($lastError == 75) { return $this->returnRestError(1049, 'Could not create user based on Facebook token. Email address ' . $blockbusterFacebook->getUserEmail() . ' already in use', 'Du skal først logge ind med ' . $blockbusterFacebook->getUserEmail() . ' før du kan tilknytte din konto til Facebook', 404); } else { return $this->returnRestError(1045, 'Could not create user based on Facebook token', null, 404); } } // only look at "newsletter" in GET login if we created user if ($newsletter !== false) { $this->User->setSetting($status->Data->UserID, User::SETTING_BB_PERMISSION_EMAIL, $newsletter == (int) 1); } $this->addOnboardingMoviesToBlockbusterUser($status->Data->UserID, $status->Data->UserLogin, $status->Data->EmailAddress); $session_id = Facades\BlockBusterLogin::facebookLogin($facebookUserId, $token); } } else { $session_id = Facades\BlockBusterLogin::login($username, $password); } if ($session_id) { $domain = 'xmpp.blockbuster.dk'; $userinfo = Facades\BlockBusterLogin::getUserInfo($session_id); } } } } // SA-1620 force all sessions to 25 minutes due to YSPro bug with session times //$expireHours = ($flavour == 'blockbuster') ? 1.5 : 11.5; $expireHours = 0.42; // 25 minutes if ($session_id) { // SA-1421 cache session_id -> user for greater logging capabilities $this->Memcaching->set('yspro_sessionid' . $session_id, $username, 86400); // cache session->user 24hours LogContext::add("username", $username); LogContext::add("yspro_session", $session_id); $isUserAtHome = isUserAtHome($flavour, getClientIp(), $userinfo); $response = array('session_id' => $session_id, 'expiresinhours' => $expireHours, 'xmpp' => with(new \OdpPermissions\GuestLoginToken())->get(true, (int) $userinfo->userId, $domain)); $this->response($response); } else { if (!$presentableError) { $presentableError = 'Du har indtastet forkert brugernavn eller adgangskode'; } return $this->returnRestError(1000, 'Wrong username or password', $presentableError, 404); } }
/** * Decryption using openssl's AES or phpseclib's AES * (phpseclib uses mcrypt when it is available) * * @param string $encdata encrypted data * @param string $secret the secret * * @return string original data */ public function cookieDecrypt($encdata, $secret) { if (is_null($this->_cookie_iv)) { $this->_cookie_iv = base64_decode($_COOKIE['pma_iv-' . $GLOBALS['server']], true); } if (strlen($this->_cookie_iv) < $this->getIVSize()) { $this->createIV(); } if ($this->_useOpenSSL()) { return openssl_decrypt($encdata, 'AES-128-CBC', $secret, 0, $this->_cookie_iv); } else { $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); $cipher->setIV($this->_cookie_iv); $cipher->setKey($secret); return $cipher->decrypt(base64_decode($encdata)); } }
/** * Decrypt the given AES ciphertext * * The mode is CBC, the key is derived using pbkdf2 * * @param string $ciphertext The encrypted data * @param string $secret The secret/password that shall be used * @return string The decrypted data */ function auth_decrypt($ciphertext, $secret) { $iv = substr($ciphertext, 0, 16); $cipher = new Crypt_AES(); $cipher->setPassword($secret); $cipher->setIV($iv); return $cipher->decrypt(substr($ciphertext, 16)); }
/** * Validate the signature and date of the message, then * decrypt it. * * @param string $secret * @param string $body * @param string $signature * @return string * Plain text. * @throws InvalidMessageException */ public static function authenticateThenDecrypt($secret, $body, $signature) { $keys = self::deriveAesKeys($secret); $localHmac = hash_hmac('sha256', $body, $keys['auth']); if (!self::hash_compare($signature, $localHmac)) { throw new InvalidMessageException("Incorrect hash"); } list($jsonEnvelope, $jsonEncrypted) = explode(Constants::PROTOCOL_DELIM, $body, 2); if (strlen($jsonEnvelope) > Constants::MAX_ENVELOPE_BYTES) { throw new InvalidMessageException("Oversized envelope"); } $envelope = json_decode($jsonEnvelope, TRUE); if (!$envelope) { throw new InvalidMessageException("Malformed envelope"); } if (!is_numeric($envelope['ttl']) || Time::getTime() > $envelope['ttl']) { throw new InvalidMessageException("Invalid TTL"); } if (!is_string($envelope['iv']) || strlen($envelope['iv']) !== Constants::AES_BYTES * 2 || !preg_match('/^[a-f0-9]+$/', $envelope['iv'])) { // AES_BYTES (32) ==> bin2hex ==> 2 hex digits (4-bit) per byte (8-bit) throw new InvalidMessageException("Malformed initialization vector"); } $jsonPlaintext = UserError::adapt('Civi\\Cxn\\Rpc\\Exception\\InvalidMessageException', function () use($jsonEncrypted, $envelope, $keys) { $cipher = new \Crypt_AES(CRYPT_AES_MODE_CBC); $cipher->setKeyLength(Constants::AES_BYTES); $cipher->setKey($keys['enc']); $cipher->setIV(BinHex::hex2bin($envelope['iv'])); return $cipher->decrypt($jsonEncrypted); }); return $jsonPlaintext; }
function getPassword($pwd = null, $iv_field = "iv") { if (is_null($pwd)) { $pwd = $this->password; if (!$this->password) { return ""; } } try { $master_key_filepath = CAppUI::conf("master_key_filepath"); $master_key_filepath = rtrim($master_key_filepath, "/"); if (CExchangeSource::checkMasterKeyFile($master_key_filepath)) { CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/AES"); CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/Random"); $cipher = new Crypt_AES(CRYPT_AES_MODE_CTR); $cipher->setKeyLength(256); $keyAB = file($master_key_filepath . "/.mediboard.key"); if (count($keyAB) == 2) { $cipher->setKey($keyAB[0] . $keyAB[1]); $ivToUse = $this->{$iv_field}; if (!$ivToUse) { $clear = $pwd; $this->store(); return $clear; } $cipher->setIV($ivToUse); $decrypted = rtrim(base64_decode($pwd), ""); $decrypted = $cipher->decrypt($decrypted); if ($decrypted) { return $decrypted; } } } } catch (Exception $e) { return $pwd; } return $pwd; }
public function onStartMagicEnvelopeToXML(MagicEnvelope $magic_env, XMLStringer $xs, $flavour = null, Profile $target = null) { // Since Diaspora doesn't use a separate namespace for their "extended" // salmon slap, we'll have to resort to this workaround hack. if ($flavour !== 'diaspora') { return true; } // WARNING: This changes the $magic_env contents! Be aware of it. /** * https://wiki.diasporafoundation.org/Federation_protocol_overview * http://www.rubydoc.info/github/Raven24/diaspora-federation/master/DiasporaFederation/Salmon/EncryptedSlap * * Constructing the encryption header */ // For some reason diaspora wants the salmon slap in a <diaspora> header. $xs->elementStart('diaspora', array('xmlns' => 'https://joindiaspora.com/protocol')); /** * Choose an AES key and initialization vector, suitable for the * aes-256-cbc cipher. I shall refer to this as the “inner key” * and the “inner initialization vector (iv)”. */ $inner_key = new Crypt_AES(CRYPT_AES_MODE_CBC); $inner_key->setKeyLength(256); // set length to 256 bits (could be calculated, but let's be sure) $inner_key->setKey(common_random_rawstr(32)); // 32 bytes from a (pseudo) random source $inner_key->setIV(common_random_rawstr(16)); // 16 bytes is the block length /** * Construct the following XML snippet: * <decrypted_header> * <iv>((base64-encoded inner iv))</iv> * <aes_key>((base64-encoded inner key))</aes_key> * <author> * <name>Alice Exampleman</name> * <uri>acct:user@sender.example</uri> * </author> * </decrypted_header> */ $decrypted_header = sprintf('<decrypted_header><iv>%1$s</iv><aes_key>%2$s</aes_key><author_id>%3$s</author_id></decrypted_header>', base64_encode($inner_key->iv), base64_encode($inner_key->key), $magic_env->getActor()->getAcctUri()); /** * Construct another AES key and initialization vector suitable * for the aes-256-cbc cipher. I shall refer to this as the * “outer key” and the “outer initialization vector (iv)”. */ $outer_key = new Crypt_AES(CRYPT_AES_MODE_CBC); $outer_key->setKeyLength(256); // set length to 256 bits (could be calculated, but let's be sure) $outer_key->setKey(common_random_rawstr(32)); // 32 bytes from a (pseudo) random source $outer_key->setIV(common_random_rawstr(16)); // 16 bytes is the block length /** * Encrypt your <decrypted_header> XML snippet using the “outer key” * and “outer iv” (using the aes-256-cbc cipher). This encrypted * blob shall be referred to as “the ciphertext”. */ $ciphertext = $outer_key->encrypt($decrypted_header); /** * Construct the following JSON object, which shall be referred to * as “the outer aes key bundle”: * { * "iv": ((base64-encoded AES outer iv)), * "key": ((base64-encoded AES outer key)) * } */ $outer_bundle = json_encode(array('iv' => base64_encode($outer_key->iv), 'key' => base64_encode($outer_key->key))); /** * Encrypt the “outer aes key bundle” with Bob’s RSA public key. * I shall refer to this as the “encrypted outer aes key bundle”. */ common_debug('Diaspora creating "outer aes key bundle", will require magic-public-key'); $key_fetcher = new MagicEnvelope(); $remote_keys = $key_fetcher->getKeyPair($target, true); // actually just gets the public key $enc_outer = $remote_keys->publicKey->encrypt($outer_bundle); /** * Construct the following JSON object, which I shall refer to as * the “encrypted header json object”: * { * "aes_key": ((base64-encoded encrypted outer aes key bundle)), * "ciphertext": ((base64-encoded ciphertextm from above)) * } */ $enc_header = json_encode(array('aes_key' => base64_encode($enc_outer), 'ciphertext' => base64_encode($ciphertext))); /** * Construct the xml snippet: * <encrypted_header>((base64-encoded encrypted header json object))</encrypted_header> */ $xs->element('encrypted_header', null, base64_encode($enc_header)); /** * In order to prepare the payload message for inclusion in your * salmon slap, you will: * * 1. Encrypt the payload message using the aes-256-cbc cipher and * the “inner encryption key” and “inner encryption iv” you * chose earlier. * 2. Base64-encode the encrypted payload message. */ $payload = $inner_key->encrypt($magic_env->getData()); //FIXME: This means we don't actually put an <atom:entry> in the payload, // since Diaspora has its own update method! Silly me. Read up on: // https://wiki.diasporafoundation.org/Federation_Message_Semantics $magic_env->signMessage(base64_encode($payload), 'application/xml'); // Since we have to change the content of me:data we'll just write the // whole thing from scratch. We _could_ otherwise have just manipulated // that element and added the encrypted_header in the EndMagicEnvelopeToXML event. $xs->elementStart('me:env', array('xmlns:me' => MagicEnvelope::NS)); $xs->element('me:data', array('type' => $magic_env->getDataType()), $magic_env->getData()); $xs->element('me:encoding', null, $magic_env->getEncoding()); $xs->element('me:alg', null, $magic_env->getSignatureAlgorithm()); $xs->element('me:sig', null, $magic_env->getSignature()); $xs->elementEnd('me:env'); $xs->elementEnd('entry'); return false; }