为AWIS创建AWS v4签名 [英] Creating a AWS v4 Signature for AWIS

查看:146
本文介绍了为AWIS创建AWS v4签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多年来,我们一直在使用AWS v2签名,现在已被v4取代.

For years we've been using the AWS v2 signature which is now replaced by v4.

我正在慢慢地完成所有步骤,但是在步骤3上一直没有解决,它要求以二进制格式输出的HMAC-SHA256加密. https://docs.aws.amazon.com/AlexaWebInfoService/latest/CalculatingSignatures. html https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html

I'm slowly working through all the steps but have come unstuck on step 3 where it's asking for HMAC-SHA256 encryptions that output in binary format. https://docs.aws.amazon.com/AlexaWebInfoService/latest/CalculatingSignatures.html https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html

我需要在经典ASP 中执行此操作,我有对SHA256进行编码的脚本,但是找不到能以二进制输出的脚本.

I need to do this in Classic ASP, I have scripts that encode SHA256 but nothing I can find that will output in binary.

我最接近的是Chilkat组件,该组件似乎从SHA256哈希输出二进制文件,但是我不知道如何实现这一点: http://www.chilkatsoft.com/refdoc/xChilkatCrypt2Ref.html#method72

The nearest I've got is the Chilkat component that seems to output binary from SHA256 hashes but I can't work out how to achieve this: http://www.chilkatsoft.com/refdoc/xChilkatCrypt2Ref.html#method72

有人可以通过脚本(asp,vbscript,javascript)或Chilkat(或其他)组件为我指明正确的方向吗?真正引起问题的是二进制输出.

Can anyone point me in the right direction either with script (asp, vbscript, javascript) or with the Chilkat (or other) component? It's the binary output that is really causing problems.

非常感谢

推荐答案

AWS V4签名生成过程让我抓狂了好几天(也是HMAC二进制输出也让我很头疼),但是可以使用pure经典ASP.这是我编写的用于生成签名的S3 URL的类(我不熟悉AWIS,但是在浏览了您链接的文档后,我可以看到签名生成过程是相同的):

The AWS V4 Signature generation process had me scratching my head for days (it was the HMAC binary output that had me stumped too), but it is possible using pure classic ASP. Here's a class I wrote for generating signed S3 URLs (I'm not familiar with AWIS, but after glancing at the documentation you linked I can see the signature generation process is the same):

Class AmazonWebServices

    Private AWS_utc, AWS_timestamp, AWS_timestamp_short, AWS_url, AWS_headers, AWS_string_to_sign, AWS_signature

    Private AWS_S3_key, AWS_S3_region, AWS_S3_version, AWS_S3_bucket, AWS_S3_host, AWS_S3_secret

    Private Sub Class_Initialize()

        ' AWS expects a UTC timestamp, if your server isn't set to UTC you will need to apply
        ' an offset to NOW() using DateAdd()

        AWS_utc = NOW() ' Or to apply an offset: DateAdd("h",-1,NOW())

        AWS_timestamp = year(AWS_utc) & zero_pad(month(AWS_utc)) & zero_pad(day(AWS_utc)) &_
        "T" & zero_pad(hour(AWS_utc)) & zero_pad(minute(AWS_utc)) & zero_pad(second(AWS_utc)) & "Z"

        AWS_timestamp_short = left(AWS_timestamp,8)

        AWS_S3_key = "XXXXXXXXXXXXXXXXXXXX"

        AWS_S3_region = "eu-west-2"

        AWS_S3_version = "2006-03-01"

        AWS_S3_bucket = "BUCKETNAME"

        AWS_S3_host = AWS_S3_bucket & ".s3." & AWS_S3_region & ".amazonaws.com"

        AWS_S3_secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

    End Sub

    public function s3_signed_url(ByVal theFile, ByVal expire)

        ' expire is the number of seconds to keep the url alive

        ' Prefix the file name with a slash

        if NOT inStr(theFile,"/") = 1 then theFile = "/" & theFile

        ' Construct the S3 URL

        AWS_url = "https://" & AWS_S3_host & theFile &_
        "?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD" &_
        "&X-Amz-Algorithm=AWS4-HMAC-SHA256" &_
        "&X-Amz-Credential=" & AWS_S3_key &_ 
            "%2F" & AWS_timestamp_short &_ 
            "%2F" & AWS_S3_region &_ 
            "%2Fs3" &_
            "%2Faws4_request" &_
        "&X-Amz-Date=" & AWS_timestamp &_
        "&X-Amz-SignedHeaders=host" &_
        "&X-Amz-Expires=" & expire &_
        "&X-Amz-Signature="

        ' Construct the GET headers

        ' headers need to be separated with just a line feed
        ' VBlf = line feed
        ' VBcr = carriage return
        ' VBcrlf = carriage return & line feed
        ' Anything but VBlf (or chr(10)) will return a signature mismatch

        AWS_headers = "GET" & VBlf &_ 
        theFile & VBlf &_ 
        "X-Amz-Algorithm=AWS4-HMAC-SHA256" &_
        "&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD" &_
        "&X-Amz-Credential=" & AWS_S3_key &_ 
            "%2F" & AWS_timestamp_short &_ 
            "%2F" & AWS_S3_region &_ 
            "%2Fs3" &_
            "%2Faws4_request" &_
        "&X-Amz-Date=" & AWS_timestamp &_ 
        "&X-Amz-Expires=" & expire &_ 
        "&X-Amz-SignedHeaders=host" & VBlf &_ 
        "host:" & AWS_S3_host & VBlf & VBlf &_ 
        "host" & VBlf &_ 
        "UNSIGNED-PAYLOAD"

        ' GET headers are hashed with SHA256

        AWS_headers = hash(AWS_headers,"SHA256","hex")

        ' Construct the string to sign

        AWS_string_to_sign = "AWS4-HMAC-SHA256" & VBlf &_ 
        AWS_timestamp & VBlf &_
        AWS_timestamp_short & "/" & AWS_S3_region & "/s3/aws4_request" & VBlf &_ 
        AWS_headers

        ' date key, generated by hashing the short timestamp using the secret key as the HMAC key

        AWS_signature = hash_hmac("AWS4" & AWS_S3_secret,AWS_timestamp_short,"SHA256","raw")    

        ' region key, generated by hashing the region using the date key as the HMAC key

        AWS_signature = hash_hmac(AWS_signature,AWS_S3_region,"SHA256","raw")

        ' service key, generated by hashing the service name using the region key as the HMAC key

        AWS_signature = hash_hmac(AWS_signature,"s3","SHA256","raw")        

        ' signing key, generated by hashing the request type using the service key as the HMAC key

        AWS_signature = hash_hmac(AWS_signature,"aws4_request","SHA256","raw")

        ' signature, generated by hashing the "string to sign" using the signing key as the HMAC key

        AWS_signature = hash_hmac(AWS_signature,AWS_string_to_sign,"SHA256","hex")

        ' Return the complete URL with signature

        s3_signed_url = AWS_url & AWS_signature

    end function

    private function hash(ByVal input, ByVal alg, ByVal encoding)
        ' Convert the input to bytes if not already
        if NOT vartype(input) = 8209 then input = string_to_UTF8_bytes(input)
        Dim hAlg : Set hAlg = Server.CreateObject("System.Security.Cryptography." & get_hash_class(alg))
            hash = binary_encode(hAlg.ComputeHash_2((input)),encoding)     
        set hAlg = nothing
    end function

    private function hash_hmac(ByVal secret, ByVal message, ByVal alg, ByVal encoding)
        ' Convert the input to bytes if not already
        if NOT vartype(secret) = 8209 then secret = string_to_UTF8_bytes(secret)
        if NOT vartype(message) = 8209 then message = string_to_UTF8_bytes(message)
        Dim hAlg : Set hAlg = Server.CreateObject("System.Security.Cryptography." & get_hmac_class(alg))
            hAlg.Initialize() 
            hAlg.key = secret
            hash_hmac = binary_encode(hAlg.ComputeHash_2((message)),encoding)             
       set hAlg = nothing
    end function

    private function binary_encode(ByVal binary, ByVal encoding)
        encoding = lCase(encoding)
        if encoding = "raw" then
            binary_encode = binary
            exit function
        end if
        Dim enc : Set enc = Server.CreateObject("MSXML2.DomDocument").CreateElement("encode")
            if encoding = "base64" OR encoding = "b64" then
                ' base64 string
                enc.dataType = "bin.base64"
                enc.nodeTypedValue = binary
                binary_encode = enc.Text 
            else
                ' hexadecimal string
                enc.dataType = "bin.hex"
                enc.nodeTypedValue = binary
                binary_encode = enc.Text 
            end if
        Set enc = nothing
    end function

    private function get_hash_class(ByVal alg)
        ' get the cryptography class name for the specified hashing algorithm,
        ' return the class name for SHA1 if not found
        select case uCase(alg)
            case "MD5"
                get_hash_class = "MD5CryptoServiceProvider"
            case "SHA1"
                get_hash_class = "SHA1CryptoServiceProvider"
            case "SHA2","SHA256"
                get_hash_class = "SHA256Managed"
            case "SHA3","SHA384"
                get_hash_class = "SHA384Managed"
            case "SHA5","SHA512"
                get_hash_class = "SHA512Managed"
            case else
                get_hash_class = "SHA1CryptoServiceProvider"
        end select
    end function

    private function get_hmac_class(ByVal alg)
        ' get the cryptography class name for the specified HMAC algorithm,
        ' return the class name for SHA1 if not found
        select case uCase(alg)
            case "MD5"
                get_hmac_class = "HMACMD5"
            case "SHA1"
                get_hmac_class = "HMACSHA1"
            case "SHA3","SHA384"
                get_hmac_class = "HMACSHA384"
            case "SHA2","SHA256"
                get_hmac_class = "HMACSHA256"
            case "SHA5","SHA512"
                get_hmac_class = "HMACSHA512"
            case else
                get_hmac_class = "HMACSHA1"
        end select
    end function

    private function string_to_UTF8_bytes(ByVal aString) 
        ' convert a UTF8 string to bytes
        Dim UTF8 : Set UTF8 = Server.CreateObject("System.Text.UTF8Encoding") 
            string_to_UTF8_bytes = UTF8.GetBytes_4(aString) 
        set UTF8 = nothing
    end function

    private function zero_pad(ByVal theNum)
        if len(theNum) = 1 then
            zero_pad = cStr("0" & theNum)
        else
            zero_pad = theNum
        end if
    end function

end class

要生成24小时S3签名的URL,请执行以下操作:

To generate a 24 hour S3 signed URL:

set AWS = new AmazonWebServices

    response.write AWS.s3_signed_url("file.name",86400)

set AWS = nothing

示例输出:

https://BUCKETNAME.s3.eu-west-2.amazonaws.com/file.name?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXXXXXXXXXXXXXXX%2F20190404%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20190404T130643Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Signature=4e1ef2a12c304de0896f5faa2a472be5f66724d3c9778a73a1d623d30769c162

Time to execute: 0.00391s

您在问题中也提到了奇尔卡特. Chilkat实际上可以为您生成v4签名:

You also mentioned Chilkat in your question. Chilkat can actually generate v4 signatures for you:

https://www.chilkatsoft.com/refdoc/xChilkatAuthAwsRef.html

https://www.example-code.com/asp/aws_pre_signed_url_v4.asp

它确实需要许可证.我几年前买了一个,我强烈推荐给仍然使用Classic ASP的任何人.

It does require a license though. I bought one a few years back and I'd highly recommend it for anyone who still uses Classic ASP.

这篇关于为AWIS创建AWS v4签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆