Friday, February 17, 2012

Get Amazon S3 Resource URL with Powershell

I've been working on automating our build and deployment process recently. We are storing our binaries in S3 and I needed a script to pull the binaries from S3.

I thought this might help other people, so here you go.


# http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth

#Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ) );

#StringToSign = HTTP-VERB + "\n" +
# Content-MD5 + "\n" + # is empty for s3 request
# Content-Type + "\n" + # is empty for s3 request
# Expires + "\n" +
# CanonicalizedAmzHeaders +
# CanonicalizedResource; # relative URL kinda?

function get-s3Url ($server, $resourceUrl, $accessKey, $secretKey, $expireDate)
{
$s3BaseTime = [System.DateTime]::Parse("1970-01-01T00:00:00.0000000Z")
$exipires = [Convert]::ToInt32($expireDate.Subtract($s3BaseTime).TotalSeconds).ToString()
$stringToSign = "GET`n" + "`n" + "`n" + "$exipires`n" + "$resourceUrl"

$sha = new-object System.Security.Cryptography.HMACSHA1
$utf8 = New-Object System.Text.utf8encoding
$sha.Key = $utf8.Getbytes($secretKey)
$seedBytes = $utf8.GetBytes($stringToSign)
$digest = $sha.ComputeHash($seedBytes)
$base64Encoded = [Convert]::Tobase64String($digest)
$null = [Reflection.Assembly]::LoadWithPartialName("System.Web")
$urlEncoded = [System.Web.HttpUtility]::UrlEncode($base64Encoded)

$fullUrl = $server + $resourceUrl + "?AWSAccessKeyId=" + $accessKey + "&Expires=" + $exipires + "&Signature=" + $urlEncoded
$fullUrl
}

$server = "https://s3.amazonaws.com"
$resourceUrl = "/[your bucket name]/[path to your file in s3]"
$accessKey = "[your access key]"
$secretKey = "[your secret key]"
$expires = [System.DateTime]::Now.AddMinutes(5)

$url = get-s3Url $server $resourceUrl $accessKey $secretKey $expires

Write-Host $url