Sto progettando un'API RESTful in python. Voglio usare l'autenticazione HMAC. Non sono riuscito a trovare alcuna libreria HMAC adatta, quindi sto facendo il mio. Tuttavia, voglio utilizzare uno standard noto come Autenticazione HMAC AWS v4 .
Durante la codifica di un'implementazione dell'autenticazione HMAC client e server compatibile con AWS, ho notato alcuni aspetti non comuni del design dello standard. Non riesco a cogliere pienamente le diverse scelte progettuali che sono state fatte.
Domanda 1: perché AWS utilizza una chiave di firma complessa (prodotta tramite HMAC) invece del segreto condiviso stesso?
Attività 3 : Calcola la firma 4 di AWS versione descrive:
Before you calculate a signature, you derive a signing key from your AWS secret access key. (You don't just use your secret access key to sign the request.) You then use the signing key and the string to sign that you created in Task 2: Create a String to Sign for Signature Version 4 as the inputs to a keyed hash function. The hex-encoded result from the keyed hash function is the signature.
To calculate a signature
Derive your signing key. To do this, you use your secret access key to create a series of hash-based message authentication codes (HMACs) as shown by the following pseudocode, where HMAC(key, data) represents an HMAC-SHA256 function that returns output in binary format. The result of each hash function becomes input for the next one.
Pseudocode for deriving a signing key:
kSecret = Your AWS Secret Access Key
kDate = HMAC("AWS4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "aws4_request")
Domanda 2: Non capisco lo scopo della stringa "ambito credenziale".
In passaggi 2-3 di Attività 2 ( Crea una stringa da firmare per la versione 4 di firma ), un valore di ambito di data e credenziale viene aggiunto alla stringa firmata. Qual è lo scopo di questi valori?
Lo standard già firma il timestamp UTC nell'intestazione x-amz-date
, come parte della richiesta canonica che è stata preparata nell'attività 1. Lo stesso è vero per l'identificatore di regione (us-east-1), poiché dovrebbe presumibilmente riflettersi nell'intestazione Host:
.
Append the request date value, followed by a newline character. The date is specified by using the ISO8601 Basic format via the x-amz-date header in the YYYYMMDD'T'HHMMSS'Z' format. This value must match the value you used in any previous steps.
20110909T233600Z\n
Append the credential scope value, followed by a newline character. This value is a string that includes the date (just the date, not the date and time), the region you are targeting, the service you are requesting, and a termination string ("aws4_request") in lowercase characters. The region and service name strings must be UTF-8 encoded.
20110909/us-east-1/iam/aws4_request\n
The date must be in the YYYYMMDD format. Note that the date does not include a time value.