[技术博客]阿里云签名机制字符串的C语言实现

Posted ws-1st

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[技术博客]阿里云签名机制字符串的C语言实现相关的知识,希望对你有一定的参考价值。

[技术博客]阿里云签名机制字符串的C语言实现

问题描述见:阿里云签名机制

话不多说,上字符串函数转化函数代码

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 );

以上是关于[技术博客]阿里云签名机制字符串的C语言实现的主要内容,如果未能解决你的问题,请参考以下文章

阿里云OSS的java实现生成url签名的代码示例吗

MQTT连接签名示例

阿里云OSS的java实现生成url签名的代码示例吗

Web直传阿里云OSS服务端临签名总结 2021-01-28

Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)

C语言编程实现时间片轮转算法,尽量写得简单易懂,谢谢