問題描述見:阿里雲簽名機制html
話很少說,上字符串函數轉化函數代碼函數
bool AlicloudRequest::sendV2Request() { if( query_parameters.find( "Action" ) == query_parameters.end() ) { this->errorCode = "E_INTERNAL"; this->errorMessage = "No action specified in request."; dprintf( D_ALWAYS, "No action specified in request, failing.\n" ); return false; } std::string protocol, host, httpRequestURI; if(! parseURL( serviceURL, protocol, host, httpRequestURI )) { this->errorCode = "E_INVALID_SERVICE_URL"; this->errorMessage = "Failed to parse service URL."; dprintf( D_ALWAYS, "Failed to match regex against service URL '%s'.\n", serviceURL.c_str() ); return false; } if( (protocol != "http" && protocol != "https" && protocol != "x509" && protocol != "euca3" && protocol != "euca3s" ) ) { this->errorCode = "E_INVALID_SERVICE_URL"; this->errorMessage = "Service URL not of a known protocol (http[s]|x509|euca3[s])."; dprintf( D_ALWAYS, "Service URL '%s' not of a known protocol (http[s]|x509|euca3[s]).\n", serviceURL.c_str() ); return false; } std::string hostAndPath = host + httpRequestURI; std::transform( host.begin(), host.end(), host.begin(), & tolower ); if( httpRequestURI.empty() ) { httpRequestURI = "/"; } if( protocol == "euca3" || protocol == "euca3s" ) { query_parameters.erase( "InstanceInitiatedShutdownBehavior" ); } std::string keyID; if( protocol != "x509" ) { if( ! readShortFile( this->accessKeyFile, keyID ) ) { this->errorCode = "E_FILE_IO"; this->errorMessage = "Unable to read from accesskey file '" + this->accessKeyFile + "'."; dprintf( D_ALWAYS, "Unable to read accesskey file '%s', failing.\n", this->accessKeyFile.c_str() ); return false; } trim( keyID ); query_parameters.insert( std::make_pair( "AccessKeyId", keyID ) ); } std::stringstream ss; ss<<rand(); std::string randnum = ss.str(); query_parameters.insert( std::make_pair( "SignatureMethod", "HMAC-SHA1" ) ); query_parameters.insert( std::make_pair( "SignatureNonce", randnum ) ); query_parameters.insert( std::make_pair( "SignatureVersion", "1.0" ) ); Throttle::now( & signatureTime ); time_t now; time( & now ); //now+=28800; struct tm brokenDownTime; gmtime_r( & now, & brokenDownTime ); char iso8601[32]; strftime(iso8601, sizeof(iso8601), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); query_parameters.insert( std::make_pair( "Timestamp", iso8601 ) ); std::string stringToSign = "POST&%2F&" //+ host + "\n" //+ httpRequestURI + "\n" + alicloudURLEncode(canonicalQueryString); std::string saKey; if( protocol == "x509" ) { saKey = std::string( "not-the-DN" ); dprintf( D_FULLDEBUG, "Using '%s' as secret key for x.509\n", saKey.c_str() ); } else { if( ! readShortFile( this->secretKeyFile, saKey ) ) { this->errorCode = "E_FILE_IO"; this->errorMessage = "Unable to read from secretkey file '" + this->secretKeyFile + "'."; dprintf( D_ALWAYS, "Unable to read secretkey file '%s', failing.\n", this->secretKeyFile.c_str() ); return false; } trim( saKey ); } unsigned int mdLength = 0; unsigned char messageDigest[EVP_MAX_MD_SIZE]; const unsigned char * hmac = HMAC( EVP_sha1(), saKey.c_str(), saKey.length(), (const unsigned char *)stringToSign.c_str(), stringToSign.length(), messageDigest, & mdLength ); if( hmac == NULL ) { this->errorCode = "E_INTERNAL"; this->errorMessage = "Unable to calculate query signature (SHA1 HMAC)."; dprintf( D_ALWAYS, "Unable to calculate SHA1 HMAC to sign query, failing.\n" ); return false; } char * base64Encoded = condor_base64_encode( messageDigest, mdLength ); std::string signatureInBase64 = base64Encoded; free( base64Encoded ); std::string postURI; if( protocol == "x509" ) { postURI = "https://" + hostAndPath; } else if( protocol == "euca3" ) { postURI = "http://" + hostAndPath; } else if( protocol == "euca3s" ) { postURI = "https://" + hostAndPath; } else { postURI = this->serviceURL; } dprintf( D_FULLDEBUG, "Request URI is '%s'\n", postURI.c_str() ); size_t index = canonicalQueryString.find( "AccessKeyId=" ); if( index != std::string::npos ) { size_t skipLast = canonicalQueryString.find( "&", index + 14 ); char swap = canonicalQueryString[ index + 15 ]; canonicalQueryString[ index + 15 ] = '\0'; char const * cqs = canonicalQueryString.c_str(); if( skipLast == std::string::npos ) { dprintf( D_FULLDEBUG, "Post body is '%s...'\n", cqs ); } else { dprintf( D_FULLDEBUG, "Post body is '%s...%s'\n", cqs, cqs + skipLast ); } canonicalQueryString[ index + 15 ] = swap; } else { dprintf( D_FULLDEBUG, "Post body is '%s'\n", canonicalQueryString.c_str() ); } return sendPreparedRequest( protocol, postURI, canonicalQueryString ); }