0
public static void main(String[] args) throws SignatureException {
    String data = "GET"+"\n"+"webservices.amazon.com"+"\n"+"/onca/xml"+"\n"+"AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&ItemId=0679722769&Operation=ItemLookup&ResponeGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06";
    String key = "1234567890";
    String result = calculateRFC2104HMAC(data, key);
    System.out.println(result);

}

private static final String HMAC_SHA_ALGORITHM = "HmacSHA256";


public static String calculateRFC2104HMAC(String data, String key)throws java.security.SignatureException{
    String result;
    try {

    // get an hmac_sha256 key from the raw key bytes
    SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF-8"), HMAC_SHA_ALGORITHM);

    // get an hmac_sha256 Mac instance and initialize with the signing key
    Mac mac = Mac.getInstance(HMAC_SHA_ALGORITHM);
    mac.init(signingKey);

    // compute the hmac256 on input data bytes
    byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));

    // base64-encode the hmac256
    result = Base64.encodeBase64String(rawHmac);

    } catch (Exception e) {
        throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
    }
    return result;
    }

したがって、AWS の sha256 を使用してこの hmac を計算しようとしていますが、この例は AWS の公式ドキュメントから取得したものですが、期待どおりの結果が得られません: http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide /AuthJavaSampleHMACSignature.html変更されたのはアルゴリズムだけで、プログラムは壊れませんでした。動作するはずですが、動作しません。

私が得る結果: k1T/qvVoXgEvmdFhTEh71vLDznqEVCyKcslA5RRSB6s= 私が期待する結果: M/y0+EAFFGaUAp4bWv/WEuXYah99pVsxvqtAuC8YN7I=

誰が何が間違っているのか分かりませんか?

4

2 に答える 2

0

AWS は 2 つの異なる HMAC 関数を使用します。最初の関数は文字列表現を返し、もう 1 つはバイナリ表現を返します。これは、OpenSSL を使用した私の C++ 実装からのものです。

string hmacHex(string key, string msg)
{
    unsigned char hash[32];

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, &key[0], key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, (unsigned char*)&msg[0], msg.length());
    unsigned int len = 32;
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);

    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (int i = 0; i < len; i++)
    {   
        ss << std::hex << std::setw(2)  << (unsigned int)hash[i];
    }

    return (ss.str());
}

文字列の実装

string hmac(string key, string msg)
{
    unsigned char hash[32];

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, &key[0], key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, ( unsigned char* )&msg[0], msg.length());
    unsigned int len = 32;
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);

    std::stringstream ss;
    ss << std::setfill('0');
    for (int i = 0; i < len; i++)
    {
        ss  << hash[i];
    }

    return (ss.str());
}

Java を使用している場合は、対応する SDK を使用することをお勧めします。私の経験では、API はかなり急速に変化する傾向があります。

于 2015-06-11T23:02:07.833 に答える
0

改行文字の解釈方法に関係している可能性があります。\n は、OS に応じて、cr、lf、または cr-lf になります。

于 2013-09-12T05:40:01.540 に答える