【问题标题】:Hmac Sha256 incorrect result value AWS-JavaHmac Sha256 不正确的结果值 AWS-Java
【发布时间】:2015-06-12 08:27:07
【问题描述】:
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;
    }

所以我试图用 sha256 为 AWS 计算这个 hmac,但我没有得到预期的结果,即使这个例子取自官方 AWS 文档:http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AuthJavaSampleHMACSignature.html 唯一改变的是算法,它确实不破坏程序,所以它应该可以工作,但它没有。

我得到的结果:k1T/qvVoXgEvmdFhTEh71vLDznqEVCyKcslA5RRSB6s= 我期望的结果:M/y0+EAFFGaUAp4bWv/WEuXYah99pVsxvqtAuC8YN7I=

有人知道出了什么问题吗?

【问题讨论】:

    标签: java amazon-web-services hmac sha256


    【解决方案1】:

    这可能与换行符的解释方式有关。 \n 可以是 cr、lf 或 cr-lf,具体取决于您的操作系统。

    【讨论】:

      【解决方案2】:

      AWS 使用两个不同的 HMAC 函数,第一个返回字符串表示,另一个返回二进制表示。这是来自我使用 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 的变化很快。

      【讨论】:

        猜你喜欢
        • 2013-07-29
        • 1970-01-01
        • 1970-01-01
        • 2019-01-08
        • 2023-04-05
        • 1970-01-01
        • 2012-10-12
        • 1970-01-01
        • 2020-10-18
        相关资源
        最近更新 更多