通过 Qt (mac - OSX) 的 AWS 查询没有得到任何结果

Posted

技术标签:

【中文标题】通过 Qt (mac - OSX) 的 AWS 查询没有得到任何结果【英文标题】:AWS query through Qt (mac - OSX) is not getting any result 【发布时间】:2017-01-04 17:51:42 【问题描述】:

我目前正在尝试创建一个 C++ 程序来跟踪一堆 ASIN 的价格。 我正在使用 C++ 和 Qt(5.5 版),通过 Xcode(5.1.1)在 mac OSX 上编译。 编译时,它正在运行,但没有给出输出。我有以下警告消息(出于隐私原因,我将 AccessKey 和 AssociateTag 加密为“////////////”)

*QUrl("http://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=///////////////&AssociateTag=/////////////&ItemId=B00181T20O&Operation=ItemLookup&ResponseGroup=OfferSummary&Service=AWSECommerceService&Signature=1K69SLmTkZ9hZwwt5ualR4uDRwY%3D&SignatureMethod=HmacSHA1&Timestamp=2017-01-04T10%3A21%3A46Z")
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
qt.network.ssl: Error receiving trust for a CA certificate
"<?xml version=\"1.0\"?>\n<ItemLookupErrorResponse 
xmlns=\"http://ecs.amazonaws.com/doc/2005-10-05/\"><Error>
<Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated 
does not match the signature you provided. Check your AWS Secret Access Key and 
signing method. Consult the service documentation for details.</Message></Error>
<RequestId>f4626242-a110-43f1-9b56-b8a696b3f299</RequestId>
</ItemLookupErrorResponse>"

RET:
("", "")*

为了再次测试它,我在浏览器中复制了 URL(前几行警告消息),我也得到了同样的错误: “我们计算的请求签名与您提供的签名不匹配。请检查您的 AWS 秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。”

谁能告诉我 URL 有什么问题? 提前致谢!

【问题讨论】:

您能给我们提供一个基本的代码示例吗? 我尝试输入与我最相关的部分(我无法嵌入整个 .zip 文件) 错误应该在 SignatureMethod 上,根据我的 A|B 测试,但找不到要使用的方法。 【参考方案1】:

这是代码中最相关的部分。我怀疑我无法嵌入 .zip 文件

AWSQueryRequest::AWSQueryRequest(QObject *parent) :
    QObject(parent)

    m_netManager = new QNetworkAccessManager(this);


QString AWSQueryRequest::hmacSha1(QByteArray key, QByteArray baseString)

    int blockSize = 64; // HMAC-SHA-1 block size, defined in SHA-1 standard
    if (key.length() > blockSize)
    
        // if key is longer than block size (64), reduce key length with SHA-1 compression
        key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
    

    QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
    QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "quot;
    // ascii characters 0x36 ("6") and 0x5c ("quot;) are selected because they have large
    // Hamming distance (http://en.wikipedia.org/wiki/Hamming_distance)

    for (int i = 0; i < key.length(); i++)
    
        innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length
        outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length
    

    // result = hash ( outerPadding CONCAT hash ( innerPadding CONCAT baseString ) ).toBase64
    QByteArray total = outerPadding;
    QByteArray part = innerPadding;
    part.append(baseString);
    total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
    QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);
    return hashed.toBase64();


QByteArray AWSQueryRequest::getTimeStamp()

    QDateTime dateTime = QDateTime::currentDateTimeUtc();
    return dateTime.toString(Qt::ISODate).toUtf8();


QByteArray AWSQueryRequest::createSignature(const QMap<QString,QString> & queryItems)

    QUrl url(END_POINT);
    QString stringToSign = "GET\n";
    stringToSign.append(url.host() + "\n");
    stringToSign.append(url.path() + "\n");

    QList<QString> keys = queryItems.keys();
    for( int i=0; i < keys.count() ; ++i )
    
        stringToSign.append(keys[i]+"="+queryItems[keys[i]]);
        if( i != keys.count() -1  )
            stringToSign.append("&");
    
    QString signature = hmacSha1(AWS_PASS, stringToSign.toUtf8());
    return QUrl::toPercentEncoding(signature);

#if 0
QByteArray AWSQueryRequest::createSignature(const QList< QPair<QString,QString> > & queryItems)

    QUrl url(END_POINT);
    QString stringToSign = "GET\n";
    stringToSign.append(url.host() + "\n");
    stringToSign.append(url.path() + "\n");

    for (int i=0; i<queryItems.count(); ++i)
    
        QPair<QString,QString> pairValue = queryItems[i];
        stringToSign.append(pairValue.first+"="+pairValue.second);
        if( i != queryItems.count() -1)
            stringToSign.append("&");
    

    QString signature = hmacSha1(AWS_PASS, stringToSign.toUtf8());
    return QUrl::toPercentEncoding(signature);

#endif
QUrl AWSQueryRequest::createUrl( const QMap< QString,QString >& queryItems )

    QUrl url(END_POINT);
    QUrlQuery query;
    QMapIterator<QString, QString> it(queryItems);
    while (it.hasNext())
    
        it.next();
        query.addQueryItem(it.key().toUtf8(), it.value().toUtf8());
    
    url.setQuery(query);
    return url;


【讨论】:

以上是关于通过 Qt (mac - OSX) 的 AWS 查询没有得到任何结果的主要内容,如果未能解决你的问题,请参考以下文章

使用 Qt 在 OS X/Mac 上构建 C++ 库

在 Mac OSX 上安装 Qt 的调试版本

Mac OSX 10.9 上的 Qt 部署

如何在 Mac OSX 上将 DCMTK 与 Qt 链接

在 Mac OSX 上重定位后修补 Qt 二进制文件的脚本

在 Mac osx 下将 OpenGL 链接到 Qt Creator