Chr*_*ell 12 rest vbscript wsh amazon-s3 asp-classic
我对这里的错误感到困惑......
<script language="javascript" runat="server">
function GMTNow(){return new Date().toGMTString()}
</script>
<%
Const AWS_BUCKETNAME = "uk-bucketname"
Const AWS_ACCESSKEY = "GOES HERE"
Const AWS_SECRETKEY = "SECRET"
LocalFile = Server.Mappath("/test.jpg")
Dim sRemoteFilePath
sRemoteFilePath = "/files/test.jpg" 'Remote Path, note that AWS paths (in fact they aren't real paths) are strictly case sensitive
Dim strNow
strNow = GMTNow() ' GMT Date String
Dim StringToSign
StringToSign = Replace("PUT\n\nimage/jpeg\n\nx-amz-date:" & strNow & "\n/"& AWS_BUCKETNAME & sRemoteFilePath, "\n", vbLf)
Dim Signature
Signature = BytesToBase64(HMACSHA1(AWS_SECRETKEY, StringToSign))
Dim Authorization
Authorization = "AWS " & AWS_ACCESSKEY & ":" & Signature
Dim AWSBucketUrl
AWSBucketUrl = "http://s3.amazonaws.com/" & AWS_BUCKETNAME
With Server.CreateObject("Microsoft.XMLHTTP")
.open "PUT", AWSBucketUrl & sRemoteFilePath, False
.setRequestHeader "Authorization", Authorization
.setRequestHeader "Content-Type", "image/jpeg"
.setRequestHeader "Host", AWS_BUCKETNAME & ".s3.amazonaws.com"
.setRequestHeader "x-amz-date", strNow
.send GetBytes(LocalFile) 'Get bytes of local file and send
If .status = 200 Then ' successful
Response.Write "<a href="& AWSBucketUrl & sRemoteFilePath &" target=_blank>Uploaded File</a>"
Else ' an error ocurred, consider xml string of error details
Response.ContentType = "text/xml"
Response.Write .responseText
End If
End With
Function GetBytes(sPath)
dim fs,f
set fs=Server.CreateObject("Scripting.FileSystemObject")
set f=fs.GetFile(sPath)
GetBytes = f.Size
set f=nothing
set fs=nothing
End Function
Function BytesToBase64(varBytes)
With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64")
.dataType = "bin.base64"
.nodeTypedValue = varBytes
BytesToBase64 = .Text
End With
End Function
Function HMACSHA1(varKey, varValue)
With Server.CreateObject("System.Security.Cryptography.HMACSHA1")
.Key = UTF8Bytes(varKey)
HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue))
End With
End Function
Function UTF8Bytes(varStr)
With Server.CreateObject("System.Text.UTF8Encoding")
UTF8Bytes = .GetBytes_4(varStr)
End With
End Function
%>
Run Code Online (Sandbox Code Playgroud)
现在得到错误.
msxml3.dll error '800c0008'
The download of the specified resource has failed.
/s3.asp, line 39
Run Code Online (Sandbox Code Playgroud)
据我所知,我想解释一下S3 Rest Api是如何工作的.
首先,您需要了解亚马逊接受的字符串应该是什么.
格式:
StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource;
Run Code Online (Sandbox Code Playgroud)
生成签名字符串:
Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) );
Run Code Online (Sandbox Code Playgroud)
传递授权标题:
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于没有为经典asp发布任何SDK,因此您将逐字节播放.所以,应该通过阅读整个页面来理解 http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html
对于要在格式中看到的字符串进行签名,API会保留三个本机标头.内容类型,内容-MD5和日期.这些标题必须存在于字符串中以进行签名,即使您的请求没有标题名称也不是空的,只是它的值.有一个例外,Date
如果x-amz-date
请求中已存在标头,则标头必须为空才能签名.然后,如果请求具有规范的亚马逊标头,则应将它们添加为键值对x-amz-headername:value
.但是,还需要考虑多个标头的另一个例外.多个标题应合并为一个标题,其值为逗号分隔.
正确
X-AMZ-headername:值1,值
错误
x-amz-headername:value1 \n
x-amz-headername:value2
最重要的是,标题必须按字符串中的组升序才能签名.首先,保留标题按升序排列,然后是标准标题按升序排列.
我建议使用DomDocument
功能来生成Base64编码的字符串.此外,您可以使用.Net的互操作代替Windows脚本组件(.wsc文件),System.Security.Cryptography
以便更有效地生成密钥哈希System.Text
.所有这些互操作性都可以在今天的IIS Web服务器中使用.
因此,作为一个例子,我写下面的脚本只是将文件发送到您指定的存储桶.考虑并测试它.
假定的本地文件名是myimage.jpg
,并将以相同的名称上传到存储桶的根目录.
<script language="javascript" runat="server">
function GMTNow(){return new Date().toGMTString()}
</script>
Run Code Online (Sandbox Code Playgroud)
<%
Const AWS_BUCKETNAME = "uk-bucketname"
Const AWS_ACCESSKEY = "GOES HERE"
Const AWS_SECRETKEY = "SECRET"
LocalFile = Server.Mappath("/test.jpg")
Dim sRemoteFilePath
sRemoteFilePath = "/files/test.jpg" 'Remote Path, note that AWS paths (in fact they aren't real paths) are strictly case sensitive
Dim strNow
strNow = GMTNow() ' GMT Date String
Dim StringToSign
StringToSign = Replace("PUT\n\nimage/jpeg\n\nx-amz-date:" & strNow & "\n/"& AWS_BUCKETNAME & sRemoteFilePath, "\n", vbLf)
Dim Signature
Signature = BytesToBase64(HMACSHA1(AWS_SECRETKEY, StringToSign))
Dim Authorization
Authorization = "AWS " & AWS_ACCESSKEY & ":" & Signature
Dim AWSBucketUrl
AWSBucketUrl = "https://" & AWS_BUCKETNAME & ".s3.amazonaws.com"
With Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
.open "PUT", AWSBucketUrl & sRemoteFilePath, False
.setRequestHeader "Authorization", Authorization
.setRequestHeader "Content-Type", "image/jpeg"
.setRequestHeader "Host", AWS_BUCKETNAME & ".s3.amazonaws.com"
.setRequestHeader "x-amz-date", strNow
.send GetBytes(LocalFile) 'Get bytes of local file and send
If .status = 200 Then ' successful
Response.Write "<a href="& AWSBucketUrl & sRemoteFilePath &" target=_blank>Uploaded File</a>"
Else ' an error ocurred, consider xml string of error details
Response.ContentType = "text/xml"
Response.Write .responseText
End If
End With
Function GetBytes(sPath)
With Server.CreateObject("Adodb.Stream")
.Type = 1 ' adTypeBinary
.Open
.LoadFromFile sPath
.Position = 0
GetBytes = .Read
.Close
End With
End Function
Function BytesToBase64(varBytes)
With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64")
.dataType = "bin.base64"
.nodeTypedValue = varBytes
BytesToBase64 = .Text
End With
End Function
Function HMACSHA1(varKey, varValue)
With Server.CreateObject("System.Security.Cryptography.HMACSHA1")
.Key = UTF8Bytes(varKey)
HMACSHA1 = .ComputeHash_2(UTF8Bytes(varValue))
End With
End Function
Function UTF8Bytes(varStr)
With Server.CreateObject("System.Text.UTF8Encoding")
UTF8Bytes = .GetBytes_4(varStr)
End With
End Function
%>
Run Code Online (Sandbox Code Playgroud)
Amazon 签名的 url 编码方式必须与 VBSCript 编码方式略有不同。以下函数将正确编码结果:
\n\nJScript 版本:
\n\nfunction amazonEncode(s)\n{\n return Server.UrlEncode(s).replace(/\\+/g,"%20").replace(/\\%2E/g,".").replace(/\\%2D/g,"-").replace(/\\%7E/g,"~").replace(/\\%5F/g,"_");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nVBScript 版本:
\n\nfunction amazonEncode(s)\n dim retval\n retval = Server.UrlEncode(s)\n retval = replace(retval,"+","%20")\n retval = replace(retval,"%2E",".")\n retval = replace(retval,"%2D","-")\n retval = replace(retval,"%7E","~")\n retval = replace(retval,"%5F","_")\n amazonEncode = retval\nend function\n
Run Code Online (Sandbox Code Playgroud)\n\n至于base64,我使用了.NET 已经为其构建的功能。我必须创建一个 DLL 来包装它,以便我可以从 JScript(或 VBScript)使用它。
\n\n创建该 dll 的方法如下:
\n\nDownload the free C# 2010 Express and install it.\nYou also need to use two other tools that you won\xe2\x80\x99t have a path to, so you will need to add the path to your PATH environment variable, so at a cmd prompt search for regasm.exe, guidgen.exe and sn.exe (you might find several versions \xe2\x80\x93 select the one with the latest date).\n\xe2\x80\xa2 cd\\\n\xe2\x80\xa2 dir/s regasm.exe\n\xe2\x80\xa2 dir/s sn.exe\n\xe2\x80\xa2 dir/s guidgen.exe\n\n\nSo as an example, a COM object that has just one method which just returns \xe2\x80\x9cHello\xe2\x80\x9d:\nOur eventual aim is to use it like this:\n<%@Language=JScript%>\n<%\nvar x = Server.CreateObject("blah.whatever");\nResponse.Write(x.someMethod());\n%>\n\nor \n\n<%@Language=VBScript%>\n<%\ndim x\nset x = Server.CreateObject("blah.whatever")\nResponse.Write x.someMethod()\n%>\n\n\xe2\x80\xa2 Start C# and create a new project\n\xe2\x80\xa2 Select \xe2\x80\x9cEmpty Project\xe2\x80\x9d\n\xe2\x80\xa2 Give it a name \xe2\x80\x93 this becomes the namespace by default (the blah in the sample above)\n\xe2\x80\xa2 Next save the project (so you know where to go for the next bit). This will create a folder structure like so:\no blah this contains your solution files that the editor needs (blah.sln etc)\n\xef\x82\xa7 blah this contains your source code and project files\n\xe2\x80\xa2 bin\no Debug the compiled output ends up here\n\xe2\x80\xa2 Next, using the cmd console, navigate to the root blah folder and create a key pair file:\n sn \xe2\x80\x93k key.snk\n\xe2\x80\xa2 Next you need a unique guid (enter guidgen at the cmd prompt)\no Select registry format\no Click \xe2\x80\x9cNew Guid\xe2\x80\x9d\no Click \xe2\x80\x9cCopy\xe2\x80\x9d\n\xe2\x80\xa2 Back to C# editor \xe2\x80\x93 from the menu, select Project \xe2\x80\x93 Add Class\n\xe2\x80\xa2 Give it a name \xe2\x80\x93 this is the whatever in the sample above\n\xe2\x80\xa2 After the opening brace just after the namespace line type:\n [GuidAttribute(\xe2\x80\x9cpaste your guid here\xe2\x80\x9d)]\n remove the curly brackets from your pasted guid\n\xe2\x80\xa2 You will need to add another \xe2\x80\x9cusing\xe2\x80\x9d at the top\n using System.Runtime.InteropServices;\n\xe2\x80\xa2 Finally you need to create someMethod\n\nThe final C# code looks like this (the bits in red may be different in your version):\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Runtime.InteropServices;\n\nnamespace blah\n{\n [GuidAttribute("AEF4F27F-9E97-4189-9AD5-64386A1699A7")]\n public class whatever\n {\n public string someMethod()\n {\n return "Hello";\n }\n }\n}\n\n\xe2\x80\xa2 Next, from the menu, select Project \xe2\x80\x93 Properties\no On the left, select Application and, for the Output type dropdown, select \xe2\x80\x9cClass Library\xe2\x80\x9d\no On the left, select Signing and tick the \xe2\x80\x9cSign the assembly\xe2\x80\x9d box, then browse to the key.snk file you made earlier\no Save the properties (CTRL-S)\n\xe2\x80\xa2 Next build the dll (Press F6) \xe2\x80\x93 This will create a dll in the Debug folder\n\xe2\x80\xa2 Open a cmd window as administrator (right click cmd.exe and select \xe2\x80\x9cRun as Administrator\xe2\x80\x9d)\n\xe2\x80\xa2 Navigate to the Debug folder and enter the following to register the assembly:\n regasm blah.dll /tlb:blah.tlb /codebase blah\n\nThat\xe2\x80\x99s it \xe2\x80\x93 the above is a genuine COM component and will work in other applications, the example below allows for event handling and only really works in ASP due to the default property mechanism of ASP:\n
Run Code Online (Sandbox Code Playgroud)\n\nBase64 的代码是:
\n\n // returns a base 64 encoded string that has been encrypted with SHA256\n // parameters:\n // s string to encrypt\n // k key to use during encryption\n public string getBase64SHA256(string s, string k)\n {\n HMACSHA256 sha = new HMACSHA256();\n System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();\n sha.Key = encoding.GetBytes(k);\n byte[] hashBytes = sha.ComputeHash(encoding.GetBytes(s));\n return System.Convert.ToBase64String(hashBytes);\n }\n\n // returns a base 64 encoded string that has been encrypted with SHA1\n // parameters:\n // s string to encrypt\n // k key to use during encryption\n public string getBase64SHA1(string s, string k)\n {\n HMACSHA1 sha = new HMACSHA1();\n System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();\n sha.Key = encoding.GetBytes(k);\n byte[] hashBytes = sha.ComputeHash(encoding.GetBytes(s));\n return System.Convert.ToBase64String(hashBytes);\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n您需要相关的用法:
\n\nusing System.Security.Cryptography;\n
Run Code Online (Sandbox Code Playgroud)\n\n在计算 SHA 和 base64 之前,完整签名必须包含按字母顺序排列的所有查询字符串名称-值对。这是我的签名创建器功能版本:
\n\nfunction buildAmazonSignature(host,req,qstring)\n{\n var str="", i, arr = String(qstring).split("&");\n\n for (i=0; i<arr.length; i++)\n arr[i] = arr[i].split("=");\n arr.sort(amazonSortFunc);\n\n for (i=0; i<arr.length; i++)\n {\n if (str != "")\n str += "&";\n\n str += arr[i][0] + "=" + arr[i][1];\n }\n\n str = "GET\\n"+host+"\\n"+req+"\\n"+str;\n\n var utils = Server.CreateObject("FMAG.Utils");\n var b64 = utils.getBase64SHA256(str, "xxxxxxxxxx");\n utils = null;\n\n return amazonEncode(b64);\n}\n\nfunction amazonSortFunc(a,b)\n{\n return (a[0]<b[0])?-1:((a[0]>b[0])?1:0);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nVBScript 没有很好的数组排序功能,因此您必须自己解决这个问题 - 抱歉
\n\n我还有以下格式的时间戳:
\n\nYYYY-MM-DDTHH:MM:SSZ
\n\n查询字符串中的内容还包括以下内容:
\n\nAWSAccessKeyId\nSignatureMethod\nSignatureVersion\nVersion\nExpires\nAction\n
Run Code Online (Sandbox Code Playgroud)\n\n希望有帮助
\n 归档时间: |
|
查看次数: |
5386 次 |
最近记录: |