public function decrypt($msgSignature, $timestamp = null, $nonce, $postData, &$msg) { if (strlen($this->encodingAesKey) != 43) { return ErrorCode::$IllegalAesKey; } if ($timestamp == null) $timestamp = time(); $pc = new Prpcrypt($this->encodingAesKey); $encrypt = simplexml_load_string($postData, 'SimpleXMLElement', LIBXML_NOCDATA); $encrypt = $encrypt->Encrypt; $sha1 = new SHA1; $array = $sha1->getSHA1($this->token, $timestamp, $nonce, $encrypt); $ret = $array[0]; if ($ret != 0) { return $ret; } $signature = $array[1]; if ($signature != $msgSignature) { return ErrorCode::$ValidateSignatureError; } $result = $pc->decrypt($encrypt, $this->appId); if ($result[0] != 0) { return $result[0]; } $msg = $result[1]; return ErrorCode::$OK; }
public function decryptMsg($msgSignature, $timestamp = NULL, $nonce, $postData, &$msg) { if (strlen($this->encodingAesKey) != 43) { return ErrorCode::$IllegalAesKey; } $pc = new Prpcrypt($this->encodingAesKey); $xmlparse = new XMLParse(); $array = $xmlparse->extract($postData); $ret = $array[0]; if ($ret != 0) { return $ret; } if ($timestamp == NULL) { $timestamp = time(); } $encrypt = $array[1]; $touser_name = $array[2]; $sha1 = new SHA1(); $array = $sha1->getSHA1($this->token, $timestamp, $nonce, $encrypt); $ret = $array[0]; if ($ret != 0) { return $ret; } $signature = $array[1]; if ($signature != $msgSignature) { return ErrorCode::$ValidateSignatureError; } $result = $pc->decrypt($encrypt, $this->appId); if ($result[0] != 0) { return $result[0]; } $msg = $result[1]; return ErrorCode::$OK; }
public function DecryptMsg($signature, $timeStamp = null, $nonce, $encrypt, &$decryptMsg) { if (strlen($this->m_encodingAesKey) != 43) { return ErrorCode::$IllegalAesKey; } $pc = new Prpcrypt($this->m_encodingAesKey); if ($sTimeStamp == null) { $sTimeStamp = time(); } $sha1 = new SHA1(); $array = $sha1->getSHA1($this->m_token, $timeStamp, $nonce, $encrypt); $ret = $array[0]; if ($ret != 0) { return $ret; } $verifySignature = $array[1]; if ($verifySignature != $signature) { return ErrorCode::$ValidateSignatureError; } $result = $pc->decrypt($encrypt, $this->m_suiteKey); if ($result[0] != 0) { return $result[0]; } $decryptMsg = $result[1]; return ErrorCode::$OK; }
/** * Compares a given hash with a clean text password by figuring out the * algorithm that has been used and then calling the appropriate sub-class * * @see cryptography.MD5#compare() * @see cryptography.SHA1#compare() * @see cryptography.PBKDF2#compare() * * @param string $input * the cleartext password * @param string $hash * the hash the password should be checked against * @param boolean $isHash * @return boolean * the result of the comparison */ public static function compare($input, $hash, $isHash = false) { $version = substr($hash, 0, 8); if ($isHash == true) { return $input == $hash; } elseif ($version == 'PBKDF2v1') { // salted PBKDF2 return PBKDF2::compare($input, $hash); } elseif (strlen($hash) == 40) { // legacy, unsalted SHA1 return SHA1::compare($input, $hash); } elseif (strlen($hash) == 32) { // legacy, unsalted MD5 return MD5::compare($input, $hash); } else { // the hash provided doesn't make any sense return false; } }
/** * Creates an author token using the `Cryptography::hash` function and the * current Author's username and password. The default hash function * is SHA1 * * @see toolkit.Cryptography#hash() * @see toolkit.General#substrmin() * * @return string */ public function createAuthToken() { return General::substrmin(SHA1::hash($this->get('username') . $this->get('password')), 8); }
* Vectors from: http://www.febooti.com/products/filetweak/members/hash-and-crc/test-vectors/ */ $rmd160 = RMD160::compute($input); $rmd160tv = RMD160::compute(""); $rmd160hmac = RMD160::computeHMAC("1234567890123456", $input); // print "RIPEMD-160 from otv is ok: " . bool_str(Base16::encode($rmd160tv) == "9c1185a5c5e9fc54612808977ee8f548b2258d31") . "<br/>\n"; print "RIPEMD-160 HMAC in UTF-8: " . Base16::encode($rmd160hmac) . "<br/>\n"; print "RIPEMD-160 in UTF-8: " . Base16::encode($rmd160) . "<br/><br/>\n"; /** * Test SHA-1 with one official test vector and custom input. * Vectors from: http://www.febooti.com/products/filetweak/members/hash-and-crc/test-vectors/ */ $sha1 = SHA1::compute($input); $sha1tv = SHA1::compute(""); $sha1hmac = SHA1::computeHMAC("1234567890123456", $input); // print "SHA-1 from otv is ok: " . bool_str(Base16::encode($sha1tv) == "da39a3ee5e6b4b0d3255bfef95601890afd80709") . "<br/>\n"; print "SHA-1 HMAC in UTF-8: " . Base16::encode($sha1hmac) . "<br/>\n"; print "SHA-1 in UTF-8: " . Base16::encode($sha1) . "<br/><br/>\n"; /** * Test SHA-256 with one official test vector and custom input. * Vectors from: http://www.febooti.com/products/filetweak/members/hash-and-crc/test-vectors/ */ $sha256 = SHA256::compute($input); $sha256tv = SHA256::compute(""); $sha256hmac = SHA256::computeHMAC("1234567890123456", $input); // print "SHA-256 from otv is ok: " . bool_str(Base16::encode($sha256tv) == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") . "<br/>\n"; print "SHA-256 HMAC in UTF-8: " . Base16::encode($sha256hmac) . "<br/>\n"; print "SHA-256 in UTF-8: " . Base16::encode($sha256) . "<br/><br/>\n";
public function action() { if (isset($_POST['action'])) { $actionParts = array_keys($_POST['action']); $action = end($actionParts); // Login Attempted if ($action == 'login') { if (empty($_POST['username']) || empty($_POST['password']) || !Administration::instance()->login($_POST['username'], $_POST['password'])) { /** * A failed login attempt into the Symphony backend * * @delegate AuthorLoginFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who attempted to login. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginFailure', '/login/', array('username' => Symphony::Database()->cleanValue($_POST['username']))); $this->failedLoginAttempt = true; } else { /** * A successful login attempt into the Symphony backend * * @delegate AuthorLoginSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param string $username * The username of the Author who logged in. */ Symphony::ExtensionManager()->notifyMembers('AuthorLoginSuccess', '/login/', array('username' => Symphony::Database()->cleanValue($_POST['username']))); isset($_POST['redirect']) ? redirect($_POST['redirect']) : redirect(SYMPHONY_URL . '/'); } // Reset of password requested } elseif ($action == 'reset') { $author = Symphony::Database()->fetchRow(0, sprintf("\n SELECT `id`, `email`, `first_name`\n FROM `tbl_authors`\n WHERE `email` = '%1\$s' OR `username` = '%1\$s'\n ", Symphony::Database()->cleanValue($_POST['email']))); if (!empty($author)) { Symphony::Database()->delete('tbl_forgotpass', sprintf("\n `expiry` < %d", DateTimeObj::getGMT('c'))); if (!($token = Symphony::Database()->fetchVar('token', 0, "SELECT `token` FROM `tbl_forgotpass` WHERE `expiry` > '" . DateTimeObj::getGMT('c') . "' AND `author_id` = " . $author['id']))) { // More secure password token generation if (function_exists('openssl_random_pseudo_bytes')) { $seed = openssl_random_pseudo_bytes(16); } else { $seed = mt_rand(); } $token = substr(SHA1::hash($seed), 0, 16); Symphony::Database()->insert(array('author_id' => $author['id'], 'token' => $token, 'expiry' => DateTimeObj::getGMT('c', time() + 120 * 60)), 'tbl_forgotpass'); } try { $email = Email::create(); $email->recipients = $author['email']; $email->subject = __('New Symphony Account Password'); $email->text_plain = __('Hi %s,', array($author['first_name'])) . PHP_EOL . __('A new password has been requested for your account. Login using the following link, and change your password via the Authors area:') . PHP_EOL . PHP_EOL . ' ' . SYMPHONY_URL . "/login/{$token}/" . PHP_EOL . PHP_EOL . __('It will expire in 2 hours. If you did not ask for a new password, please disregard this email.') . PHP_EOL . PHP_EOL . __('Best Regards,') . PHP_EOL . __('The Symphony Team'); $email->send(); $this->_email_sent = true; $this->_email_sent_to = $author['email']; // Set this so we can display a customised message } catch (Exception $e) { $this->_email_error = General::unwrapCDATA($e->getMessage()); Symphony::Log()->pushExceptionToLog($e, true); } /** * When a password reset has occurred and after the Password * Reset email has been sent. * * @delegate AuthorPostPasswordResetSuccess * @since Symphony 2.2 * @param string $context * '/login/' * @param integer $author_id * The ID of the Author who requested the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetSuccess', '/login/', array('author_id' => $author['id'])); } else { /** * When a password reset has been attempted, but Symphony doesn't * recognise the credentials the user has given. * * @delegate AuthorPostPasswordResetFailure * @since Symphony 2.2 * @param string $context * '/login/' * @param string $email * The sanitised Email of the Author who tried to request the password reset */ Symphony::ExtensionManager()->notifyMembers('AuthorPostPasswordResetFailure', '/login/', array('email' => Symphony::Database()->cleanValue($_POST['email']))); $this->_email_sent = false; } } } }
/** * 检验消息的真实性,并且获取解密后的明文. * <ol> * <li>利用收到的密文生成安全签名,进行签名验证</li> * <li>若验证通过,则提取xml中的加密消息</li> * <li>对消息进行解密</li> * </ol> * * @param $msgSignature string 签名串,对应URL参数的msg_signature * @param $timestamp string 时间戳 对应URL参数的timestamp * @param $nonce string 随机串,对应URL参数的nonce * @param $postData string 密文,对应POST请求的数据 * @param &$msg string 解密后的原文,当return返回0时有效 * * @return int 成功0,失败返回对应的错误码 */ public function DecryptMsg($sMsgSignature, $sTimeStamp = null, $sNonce, $sPostData, &$data) { if (strlen($this->m_sEncodingAesKey) != 43) { return ErrorCode::$IllegalAesKey; } $pc = new Prpcrypt($this->m_sEncodingAesKey); //提取密文 $xmlparse = new XMLParse(); $array = $xmlparse->extract($sPostData); $ret = $array[0]; if ($ret != 0) { return $ret; } if ($sTimeStamp == null) { $sTimeStamp = time(); } $encrypt = $array[1]; $touser_name = $array[2]; //验证安全签名 $sha1 = new SHA1(); $array = $sha1->getSHA1($this->m_sToken, $sTimeStamp, $sNonce, $encrypt); $ret = $array[0]; if ($ret != 0) { return $ret; } $signature = $array[1]; if ($signature != $sMsgSignature) { return ErrorCode::$ValidateSignatureError; } $result = $pc->decrypt($encrypt, $this->m_sCorpid); if ($result[0] != 0) { return $result[0]; } $sMsg = $result[1]; $data = array(); $xml = simplexml_load_string($sMsg, 'SimpleXMLElement', LIBXML_NOCDATA); $data = api_json_decode(api_json_encode($xml), TRUE); // if($xml){ // foreach ($xml as $key => $value) { // $data[$key] = mb_convert_encoding(strval($value),"GBK","UTF-8");; // } // } return ErrorCode::$OK; }
/** * Uses `SHA1` or `MD5` to create a hash based on some input * This function is currently very basic, but would allow * future expansion. Salting the hash comes to mind. * * @param string $input * the string to be hashed * @param string $algorithm * This function supports 'md5', 'sha1' and 'pbkdf2'. Any * other algorithm will default to 'pbkdf2'. * @return string * the hashed string */ public static function hash($input, $algorithm = 'sha1') { switch ($algorithm) { case 'sha1': return SHA1::hash($input); case 'md5': return MD5::hash($input); case 'pbkdf2': default: return Crytography::hash($input, $algorithm); } }
/** * 检验消息的真实性,并且获取解密后的明文. * <ol> * <li>利用收到的密文生成安全签名,进行签名验证</li> * <li>若验证通过,则提取xml中的加密消息</li> * <li>对消息进行解密</li> * </ol> * * @param $msgSignature string 签名串,对应URL参数的msg_signature * @param $timestamp string 时间戳 对应URL参数的timestamp * @param $nonce string 随机串,对应URL参数的nonce * @param $postData string 密文,对应POST请求的数据 * @param &$msg string 解密后的原文,当return返回0时有效 * * @return int 成功0,失败返回对应的错误码 */ public function DecryptMsg($sMsgSignature, $sTimeStamp = null, $sNonce, $sPostData, &$sMsg) { if (strlen($this->m_sEncodingAesKey) != 43) { return ErrorCode::$IllegalAesKey; } $pc = new Prpcrypt($this->m_sEncodingAesKey); //提取密文 $xmlparse = new XMLParse(); $array = $xmlparse->extract($sPostData); $ret = $array[0]; if ($ret != 0) { return $ret; } if ($sTimeStamp == null) { $sTimeStamp = time(); } $encrypt = $array[1]; $touser_name = $array[2]; //验证安全签名 $sha1 = new SHA1(); $array = $sha1->getSHA1($this->m_sToken, $sTimeStamp, $sNonce, $encrypt); $ret = $array[0]; if ($ret != 0) { return $ret; } $signature = $array[1]; if ($signature != $sMsgSignature) { return ErrorCode::$ValidateSignatureError; } $result = $pc->decrypt($encrypt, $this->m_sCorpid); if ($result[0] != 0) { return $result[0]; } $sMsg = $result[1]; return ErrorCode::$OK; }
function sha1KeyedMAC($key, $message) { $c = new SHA1Context(); $s = new SHA1(); $s->reset($c); $s->input($c, $key . $message); $s->result($c); return pack('N5', $c->messageDigest[0], $c->messageDigest[1], $c->messageDigest[2], $c->messageDigest[3], $c->messageDigest[4]); }
protected function __trigger() { $result = new XMLElement(self::ROOTELEMENT); $fields = $_POST['fields']; $this->driver = Symphony::ExtensionManager()->create('members'); // Add POST values to the Event XML $post_values = new XMLElement('post-values'); // Create the post data cookie element if (is_array($fields) && !empty($fields)) { General::array_to_xml($post_values, $fields, true); } // Set the section ID $result = $this->setMembersSection($result, $_REQUEST['members-section-id']); if ($result->getAttribute('result') === 'error') { $result->appendChild($post_values); return $result; } // If a member is logged in, return early with an error if ($this->driver->getMemberDriver()->isLoggedIn()) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('message', __('You cannot generate a recovery code while being logged in.'), array('message-id' => MemberEventMessages::ALREADY_LOGGED_IN))); $result->appendChild($post_values); return $result; } // Trigger the EventPreSaveFilter delegate. We are using this to make // use of the XSS Filter extension that will ensure our data is ok to use $this->notifyEventPreSaveFilter($result, $fields, $post_values); if ($result->getAttribute('result') == 'error') { return $result; } // Add any Email Templates for this event $this->addEmailTemplates('generate-recovery-code-template'); // Check that either a Member: Username or Member: Password field // has been detected $identity = $this->driver->getMemberDriver()->setIdentityField($fields, false); if (!$identity instanceof Identity) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('message', __('No Identity field found.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS))); $result->appendChild($post_values); return $result; } // Check that a member exists first before proceeding. if (!isset($fields[$identity->get('element_name')]) or empty($fields[$identity->get('element_name')])) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS))); $result->appendChild(new XMLElement($identity->get('element_name'), null, array('label' => $identity->get('label'), 'type' => 'missing', 'message-id' => EventMessages::FIELD_MISSING, 'message' => __('%s is a required field.', array($identity->get('label')))))); $result->appendChild($post_values); return $result; } $member_id = $identity->fetchMemberIDBy($fields[$identity->get('element_name')]); if (is_null($member_id)) { $result->setAttribute('result', 'error'); $result->appendChild(new XMLElement('message', __('Member event encountered errors when processing.'), array('message-id' => MemberEventMessages::MEMBER_ERRORS))); $result->appendChild(new XMLElement($identity->get('element_name'), null, extension_Members::$_errors[$identity->get('element_name')])); $result->appendChild($post_values); return $result; } // Find the Authentication fiedl $auth = $this->driver->getMemberDriver()->section->getField('authentication'); $status = Field::__OK__; // Generate new password $newPassword = $auth->generatePassword(); $entry = $this->driver->getMemberDriver()->fetchMemberFromID($member_id); $entry_data = $entry->getData(); // Generate a Recovery Code with the same logic as a normal password $data = $auth->processRawFieldData(array('password' => $auth->encodePassword($newPassword . $member_id)), $status); // Set the Entry password to be reset and the current timestamp $data['recovery-code'] = SHA1::hash($newPassword . $member_id); $data['reset'] = 'yes'; $data['expires'] = DateTimeObj::get('Y-m-d H:i:s', time()); // If the Member has entry data for the Authentication field, update it if (array_key_exists((int) $auth->get('id'), $entry_data)) { // Overwrite the password with the old password data. This prevents // a users account from being locked out if it it just reset by a random // member of the public $data['password'] = $entry_data[$auth->get('id')]['password']; $data['length'] = $entry_data[$auth->get('id')]['length']; $data['strength'] = $entry_data[$auth->get('id')]['strength']; Symphony::Database()->update($data, 'tbl_entries_data_' . $auth->get('id'), ' `entry_id` = ' . $member_id); } else { $data['entry_id'] = $member_id; Symphony::Database()->insert($data, 'tbl_entries_data_' . $auth->get('id')); } /** * Fired just after a Member has requested a recovery code so they * can reset their password. * * @delegate MembersPostForgotPassword * @param string $context * '/frontend/' * @param integer $member_id * The Member ID of the member who just requested a recovery * code. * @param string $recovery_code * The recovery code that was generated for this Member */ Symphony::ExtensionManager()->notifyMembers('MembersPostForgotPassword', '/frontend/', array('member_id' => $member_id, 'recovery_code' => $data['recovery-code'])); // Trigger the EventFinalSaveFilter delegate. The Email Template Filter // and Email Template Manager extensions use this delegate to send any // emails attached to this event $this->notifyEventFinalSaveFilter($result, $fields, $post_values, $entry); // If a redirect is set, redirect, the page won't be able to receive // the Event XML anyway if (isset($_REQUEST['redirect'])) { redirect($_REQUEST['redirect']); } $result->setAttribute('result', 'success'); $result->appendChild(new XMLElement('recovery-code', $data['recovery-code'])); $result->appendChild($post_values); return $result; }
* 这时只需在该地址的处理中require 本文件即可。并把地址上的APPID取出来放在$APPID变量中 * 这时消息中$APPID既是appid,可以用它区分是那个公众号 */ chdir(dirname(__FILE__)); //把工作目录切换到文件所在目录 include_once dirname(__FILE__) . '/__config__.php'; //Token 验证,微信验证主体身份。如果是第三方平台,则不存在token验证 if (!$GLOBALS["HTTP_RAW_POST_DATA"]) { if (YDWX_WEIXIN_ACCOUNT_TYPE == YDWX_WEIXIN_ACCOUNT_TYPE_CROP) { //企业号的url验证 $signature = $_GET["msg_signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $echostr = $_GET["echostr"]; $pc = new Prpcrypt(YDWX_WEIXIN_ENCODING_AES_KEY); $sha1 = new SHA1(); $array = $sha1->getSHA1(YDWX_WEIXIN_TOKEN, $timestamp, $nonce, $echostr); $ret = $array[0]; if ($ret != 0) { die; } $signature = $array[1]; if ($signature != $signature) { die; } $result = $pc->decrypt($echostr, YDWX_WEIXIN_CROP_ID); if ($result[0] != 0) { die; } echo $result[1]; } else {
/** * Returns a checksum for a given input string * * @param string data * @return security.checksum.Checksum */ protected function checksumOf($data) { return SHA1::fromString($data)->getValue(); }