我正在尝试使用D编写的程序连接到AWS API。我正在使用vibe-aws module。
通过小修改(删除vibe.d
依赖关系,通过复制粘贴错过了2个函数),所有单元测试都通过了。最重要的是,我写了这个程序:
#!/usr/bin/rdmd -L-lcurl
import std.stdio;
import std.string;
import std.file;
import std.datetime;
import std.process;
import std.digest.sha;
import std.net.curl;
import std.uri;
import sigv4;
auto zone = "us-east-1";
auto service = "ec2";
void main()
{
auto accKey = environment["AWS_ACCESS_KEY"];
auto secKey = environment["AWS_SECRET_KEY"];
auto currentClock = Clock.currTime(UTC());
writeln(currentClock);
auto currentDate = cast(Date)currentClock;
auto curDateStr = currentDate.toISOString;
writeln(curDateStr);
auto currentTime = cast(TimeOfDay)currentClock;
auto curTimeStr = currentTime.toISOString;
writeln(curTimeStr);
auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z";
string[string] empty;
SignableRequest r;
r.dateString = curDateStr;
r.timeStringUTC = curTimeStr;
r.region = zone;
r.service = service;
r.canonicalRequest = CanonicalRequest(
"GET",
"/",
["action" : "DescribeInstances", "version" : "2013-10-15"],
["content-type" : "application/x-www-form-urlencoded; charset=utf-8",
"host" : service ~ ".amazonaws.com",
"x-amz-date" : xamztime],
cast(ubyte[])"");
writeln(signableString(r));
auto qParm = canonicalQueryString(r.canonicalRequest.queryParameters);
auto sigHead = canonicalHeaders(r.canonicalRequest.headers);
auto sigStr = signableString(r);
auto sigKey = signingKey(secKey, curDateStr, zone, service);
auto signature = sign(sigKey, cast(ubyte[])sigStr).toHexString().toLower();
writeln();
writeln(qParm);
writeln();
writeln(sigHead);
writeln();
writeln(sigStr);
writeln();
writeln(sigKey);
writeln(signature);
writeln();
auto client = HTTP(service ~ ".amazonaws.com/?" ~ "Action=DescribeInstances&Version=2013-10-15");
client.method = HTTP.Method.get;
client.clearRequestHeaders;
client.addRequestHeader("content-type", "application/x-www-form-urlencoded; charset=utf-8");
client.addRequestHeader("host", service ~ ".amazonaws.com");
client.addRequestHeader("x-amz-date", xamztime);
client.addRequestHeader("authorization", "AWS4-HMAC-SHA256" ~ " " ~ "Credential=" ~ accKey ~ "/" ~ xamztime ~ "/" ~ zone ~ "/" ~ service ~ "/" ~ "aws4_request" ~ ", " ~ "SignedHeaders=" ~ "content-type;host;x-amz-date" ~ ", " ~ "Signature=" ~ signature);
auto content = client.perform();
writeln(content);
}
以下是我得到的输出:
./header.d
2015-Oct-11 16:54:01.208441Z
20151011
165401
AWS4-HMAC-SHA256
20151011T165401Z
20151011/us-east-1/ec2/aws4_request
f053e1901b164a712ed6c8384754673822d609da696b5d15799304835b3870ea
action=DescribeInstances&version=2013-10-15
content-type:application/x-www-form-urlencoded; charset=utf-8
host:ec2.amazonaws.com
x-amz-date:20151011T165401Z
AWS4-HMAC-SHA256
20151011T165401Z
20151011/us-east-1/ec2/aws4_request
f053e1901b164a712ed6c8384754673822d609da696b5d15799304835b3870ea
[116, 194, 23, 247, 184, 145, 90, 14, 192, 208, 97, 210, 77, 165, 201, 250, 6, 121, 49, 208, 142, 197, 33, 93, 204, 139, 11, 29, 227, 218, 107, 240]
57fdf77b44f2d14fa688b42bc88250a6ad2e6596964a6d40037333240ca15608
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>AuthFailure</Code><Message>AWS was not able to validate the provided access credentials</Message></Error></Errors><RequestID>2cf1443d-11b9-4a16-92e7-bf30c61e550b</RequestID></Response>0
答案 0 :(得分:0)
在与之前的代码长期斗争之后,我尝试重写&#34;一对一&#34;从http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html(GET部分)的蟒蛇示例,从乞讨到D并取得圆满成功。这是使用hmac函数的清晰D. Im的工作代码,可以从2.069的phobos获得。它不是太漂亮,但我是初学者,这里是:
#!/usr/bin/rdmd -L-lcurl
module sigawsv4;
import std.stdio, std.process;
import std.digest.sha, std.digest.hmac;
import std.string;
import std.conv;
import std.datetime;
import std.net.curl;
void main()
{
auto accessKey = environment["AWS_ACCESS_KEY"];
auto secretKey = environment["AWS_SECRET_KEY"];
auto currentClock = Clock.currTime(UTC());
auto currentDate = cast(Date)currentClock;
auto curDateStr = currentDate.toISOString;
auto currentTime = cast(TimeOfDay)currentClock;
auto curTimeStr = currentTime.toISOString;
auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z";
string method = "GET";
string service = "ec2";
string host = "ec2.amazonaws.com";
string region = "us-east-1";
string endpoint = "https://ec2.amazonaws.com";
string request_parameters = "Action=DescribeInstances&Version=2013-10-15";
auto hmac_sha256(ubyte[] key, ubyte[] msg)
{
auto hmac = hmac!SHA256(key);
hmac.put(msg);
auto digest = hmac.finish;
return digest;
}
alias sign = hmac_sha256;
auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName)
{
ubyte[] kString = cast(ubyte[])("AWS4" ~ key);
auto kDate = sign(kString, cast(ubyte[])dateStamp);
auto kRegion = sign(kDate, cast(ubyte[])regionName);
auto kService = sign(kRegion, cast(ubyte[])serviceName);
auto kSigning = sign(kService, cast(ubyte[])"aws4_request");
return kSigning;
}
string canonicalURI = "/";
string canonicalQueryString = request_parameters;
string canonicalHeadersString = "host:" ~ host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n";
string signedHeaders = "host;x-amz-date";
string payloadHash = sha256Of("").toHexString.toLower;
string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ signedHeaders ~ "\n" ~ payloadHash;
string algorithm = "AWS4-HMAC-SHA256";
string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request";
string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ credentialScope ~ "\n" ~ sha256Of(canonicalRequest).toHexString.toLower;
auto signingKey = getSignatureKey(secretKey, curDateStr, region, service);
string signature = hmac_sha256(signingKey, cast(ubyte[])stringToSign).toHexString.toLower;
string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ signedHeaders ~ ", " ~ "Signature=" ~ signature;
auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString);
client.method = HTTP.Method.get;
client.addRequestHeader("x-amz-date", xamztime);
client.addRequestHeader("Authorization", authorizationHeader);
auto content = client.perform();
writeln(content);
}