public function sign(array $credentials, $httpMethod, $path, $headers, $params, $options = array()) { if (!isset($options[SignOption::EXPIRATION_IN_SECONDS])) { $expirationInSeconds = SignOption::DEFAULT_EXPIRATION_IN_SECONDS; } else { $expirationInSeconds = $options[SignOption::EXPIRATION_IN_SECONDS]; } $accessKeyId = $credentials['ak']; $secretAccessKey = $credentials['sk']; //Notice: timestamp should be UTC if (!isset($options[SignOption::TIMESTAMP])) { $timestamp = new \DateTime(); } else { $timestamp = $options[SignOption::TIMESTAMP]; } $timestamp->setTimezone(new \DateTimeZone("UTC")); //Generate authString $authString = SampleSigner::BCE_AUTH_VERSION . '/' . $accessKeyId . '/' . $timestamp->format("Y-m-d\\TH:i:s\\Z") . '/' . $expirationInSeconds; //Generate sign key with auth-string and SK using SHA-256 $signingKey = hash_hmac('sha256', $authString, $secretAccessKey); //Generate canonical uri $canonicalURI = HttpUtil::getCanonicalURIPath($path); //Generate canonical query string $canonicalQueryString = HttpUtil::getCanonicalQueryString($params); //Fill headersToSign to specify which header do you want to sign $headersToSign = null; if (isset($options[SignOption::HEADERS_TO_SIGN])) { $headersToSign = $options[SignOption::HEADERS_TO_SIGN]; } //Generate canonical headers $canonicalHeader = HttpUtil::getCanonicalHeaders(SampleSigner::getHeadersToSign($headers, $headersToSign)); $signedHeaders = ''; if ($headersToSign !== null) { $signedHeaders = strtolower(trim(implode(";", array_keys($headersToSign)))); } //Generate canonical request $canonicalRequest = "{$httpMethod}\n{$canonicalURI}\n" . "{$canonicalQueryString}\n{$canonicalHeader}"; //Generate signature with canonical request and sign key using SHA-256 $signature = hash_hmac('sha256', $canonicalRequest, $signingKey); //.Catenate result string $authorizationHeader = "{$authString}/{$signedHeaders}/{$signature}"; return $authorizationHeader; }