【问题标题】:How does an HMAC work, and why isn't this code generating the right response?HMAC 是如何工作的,为什么这段代码不能产生正确的响应?
【发布时间】:2015-01-08 04:01:39
【问题描述】:

我正试图弄清楚 HMAC 的工作原理。这是来自AWS-S3的文档

signing key = HMAC-SHA256(
  HMAC-SHA256(
    HMAC-SHA256(
      HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524")
      , "us-east-1"
    )
    , "s3"
  )
  ,"aws4_request"
)

文档说,

您可以将此示例用作测试用例来验证您的代码计算的签名;但是,您必须使用相同的存储桶名称、对象密钥、时间戳和以下示例凭据:

我不明白 Node 核心 crypto module 的工作原理或如何阅读 HMAC 规范。

上面这样描述是否正确,

var h1 = crypto.createHmac( 'sha256', "AWS4" + 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' );
  h1.setEncoding('hex');
  h1.write( '20130524' );
  h1.end();
var h2 = crypto.createHmac( 'sha256', h1.read() );
  h2.setEncoding('hex');
  h2.write( 'us-east-1' );
  h2.end();
var h3 = crypto.createHmac( 'sha256', h2.read() );
  h3.setEncoding('hex');
  h3.write( 's3' );
  h3.end();
var h4 = crypto.createHmac( 'sha256', h3.read() );
  h4.setEncoding('hex');
  h4.write('aws4_request');
  h4.end();
console.log( h4.read() )

如果是这样的话..我为什么要回来,

d949da6fe2897897d73557446db35c06dc34feb7f74e7d949c6fe9d674a02103

而且,不是文档中给出的内容:

aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404

我也尝试过以不同的方式编写此代码,因为我不确定如何处理对 .write() 的后续调用

var h1 = crypto.createHmac( 'sha256', "AWS4" + 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' );
  h1.setEncoding('hex');
  h1.write( '20130524' );
  h1.write( 'us-east-1' );
  h1.write( 's3' );
  h1.write('aws4_request');
  h1.end();
  console.log( h1.read() );

所以我想我有两个问题

  1. 基于the AWS docs 获取示例中给出的签名需要什么代码...
  2. 在加密流上连续调用 .write() 的功能是什么?它不附加。而且,它不会包含在新的 HMAC-SHA256 中。

【问题讨论】:

    标签: node.js amazon-web-services amazon-s3 hmac sha256


    【解决方案1】:

    我花了 16 个小时试图解决这个问题,并根据您最初的步骤找到了一个可行的解决方案。不是最优雅的代码,但它可以工作!见下文。

    另外,这是我的第一篇 Stack Overflow 帖子!所以请原谅任何格式错误!

    var policy = {
      "expiration": "2020-12-01T12:00:00.000Z",
      "conditions": [
        {"bucket": "XXXTHISISYOURBUCKETXXX"},
        ["starts-with", "$key", ""],
        {"x-amz-credential": "XXXTHISISYOURPUBLICKEYXXX/20150107/us-west-1/s3/aws4_request"},
        {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
        {"x-amz-date": "20150107T000000Z"}
      ]
    };
    
    var base64Policy = Buffer( JSON.stringify( policy ) , 'utf-8' ).toString( 'base64' );
    
    var a = crypto.createHmac( 'sha256' , 'AWS4' + 'XXXTHISISYOURSECRETKEYXXX' );
    
    a.write( '20150107' );
    
    a.end();
    
    var b = crypto.createHmac( 'sha256' , a.read() );
    
    b.write( 'us-west-1' );
    
    b.end();
    
    var c = crypto.createHmac( 'sha256' , b.read() );
    
    c.write( 's3' );
    
    c.end();
    
    var d = crypto.createHmac( 'sha256' , c.read() );
    
    d.write( 'aws4_request' );
    
    d.end();
    
    var e = crypto.createHmac( 'sha256' , d.read() );
    
    e.write( new Buffer( base64Policy , 'utf-8') );
    
    e.end();
    
    var signature = e.read().toString( 'hex' );
    
    console.log( signature );
    
    var credentials = {
    
      policy : base64Policy,
      signature : signature
    
    };
    

    【讨论】:

      【解决方案2】:

      [这更像是评论,但由于我不能作为客人发表评论:]

      不确定此时是否需要 setEncoding() 调用。让它处理,然后调用:

      signature = hmac.read().toString('base64');
      

      因为hmac.read() 的返回输出是Buffer 类型,所以toString() 可以正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-10
        • 2014-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 1970-01-01
        • 2017-06-08
        相关资源
        最近更新 更多