Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I calculate an AWS API signature (v4) in python?

I'm attempting to generate a signature for an Amazon Glacier upload request, using the example requests and example functions provided by the AWS documentation, but I can't make it work. At this point, I'm certain I'm missing something incredibly obvious:

#!/bin/env python

import hmac
import hashlib

# This string to sign taken from: http://docs.amazonwebservices.com/amazonglacier/latest/dev/amazon-glacier-signing-requests.html#example-signature-calculation
sts = """AWS4-HMAC-SHA256
20120525T002453Z
20120525/us-east-1/glacier/aws4_request
5f1da1a2d0feb614dd03d71e87928b8e449ac87614479332aced3a701f916743"""

# These two functions taken from: http://docs.amazonwebservices.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).hexdigest()

# The fake secret key is provided by the referenced docs
def getSignatureKey():
    kDate = sign(("AWS4" + "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY").encode('utf-8'), "20120525")
    kRegion = sign(kDate, "us-east-1")
    kService = sign(kRegion, "glacier")
    kSigning = sign(kService, "aws4_request")
    return kSigning

signature = sign(getSignatureKey(), sts)
print signature

If I run my program, I get the following hash:

$ python test.py
3431315da57da4df28f92895c75364d94b36c745896ad3e580c0a6ae403b1e05

Yet the docs clearly state:

If the secret access key, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY, is used, then the calculated signature is:

3ce5b2f2fffac9262b4da9256f8d086b4aaf42eba5f111c21681a65a127b7c2a

What am I missing?

like image 924
Christopher Avatar asked Oct 22 '12 20:10

Christopher


People also ask

What is AWS signature v4?

Signature Version 4 (SigV4) is the process to add authentication information to AWS API requests sent by HTTP. For security, most requests to AWS must be signed with an access key. The access key consists of an access key ID and secret access key, which are commonly referred to as your security credentials.

How do I validate my AWS signature?

To verify a digital signature, you can use the Verify operation. Specify the same asymmetric KMS key, message, and signing algorithm that were used to produce the signature. You can also verify the digital signature by using the public key of the KMS key outside of AWS KMS.

How do I migrate to signature 4?

To migrate to Signature Version 4, please replace your existing SMTP credentials using the appropriate procedure relative to your setup: If you generated your SMTP credentials using the SES Console, simply create new credentials and replace your existing credentials with the new ones.


1 Answers

Your function differs from theirs in one respect. You're doing

def sign(key, msg):
  return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).hexdigest()

but they're doing

def sign(key, msg):
  return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

So your derived key is wrong. You only want to be using hexdigest at the last step of the process, not when calculating the signing key.

like image 103
Frederick Cheung Avatar answered Sep 20 '22 21:09

Frederick Cheung