Wie man AWS-Signature-Version-4-Implementierungen verifiziert

English Deutsch

Sie können das Python-Paket botocore, das eine Abhängigkeit des boto3 AWS-Clients ist, verwenden, um zu verifizieren, ob Ihre Implementierung korrekte HMAC-Signaturen für einen gegebenen String-to-sign erzeugt.

Um dies zu tun, verwenden wir ein festes AmzDate, d.h. einen Zeitstempel, und feste (aber zufällige) Access-Keys. Der zu signierende String ist ebenfalls ein irgendwie zufälliger String. Das Einzige, was zählt, ist, dass keiner der zufälligen Strings leer ist und alle Werte für den Verifizierungspfad mit botocore dieselben sind wie für Ihre eigene Implementierung.

Vergleichen Sie danach die Ausgabe der botocore-Implementierung mit Ihrer eigenen benutzerdefinierten Implementierung. Während Sie Ihre Implementierung vielleicht mit verschiedenen Werten überprüfen möchten, funktioniert sie in der Praxis (vielleicht abgesehen von seltenen Randfällen), wenn sie für einen String korrekt funktioniert.

Verifizieren der Ausgabe

verify_sigv4.py
from botocore.auth import SigV4Auth
from collections import namedtuple

# Data structures for isolated testing
Credentials = namedtuple('Credentials', ['access_key', 'secret_key'])
Request = namedtuple('Request', ['context'])

amzDate = "20130524T000000Z" # Fixed date for testing
signer = SigV4Auth(Credentials(
    access_key="GBWZ45MPRGGMO2JILBXA",
    secret_key="346NO6UJCAMHLHX4SMFA"
), "s3", "global")
signature = signer.signature("ThisStringWillBeSigned", Request(
    context={"timestamp": amzDate}
))
print(signature)

Mit den in diesem Skript angegebenen Werten ist die Ausgabe

sigv4_signature.txt
3be60989db53028ca485b46a07df9287a1731df74a234ea247a99febb7c2eb31

Verifizieren von Zwischenergebnissen

Wenn das globale Ergebnis übereinstimmt, sind Sie bereits fertig. Es gibt typischerweise keine Notwendigkeit, die Zwischenergebnisse und Eingabestrings zu überprüfen.

Die Funktion SigV4Auth.signature() bietet keine Möglichkeit, auf die Zwischenergebnisse zuzugreifen. Wir können jedoch einfach ihren Quellcode kopieren, um die relevanten Zwischenergebnisse zu erhalten und diese als Hex auszugeben:

sigv4_intermediates.py
secret_key="346NO6UJCAMHLHX4SMFA"
datestamp = "20130524"
region_name = "global"
service_name = "s3"
string_to_sign = "ThisStringWillBeSigned"

sign_input =  (f"AWS4{secret_key}").encode(), datestamp
k_date = signer._sign(*sign_input)
k_region = signer._sign(k_date, region_name)
k_service = signer._sign(k_region, service_name)
k_signing = signer._sign(k_service, 'aws4_request')
sign_result = signer._sign(k_signing, string_to_sign, hex=True)

print("Sign input: ", sign_input)
print("k_date: ", k_date.hex(), "of length: ", len(k_date))
print("k_region: ", k_region.hex(), "of length: ", len(k_region))
print("k_service: ", k_service.hex(), "of length: ", len(k_service))
print("k_signing: ", k_signing.hex(), "of length: ", len(k_signing))
print("sign_result: ", sign_result)

Dies gibt aus:

sigv4_intermediates_output.txt
Sign input:  (b'AWS4346NO6UJCAMHLHX4SMFA', '20130524')
k_date:  a788ed61da3106091ac303738fe248c3d391e851858d9b048d3fddf0494cac61 of length:  32
k_region:  90331d205578b73aeaf4ef9082cbb704111d29364dcae4d4405ddfefc4e6a8b0 of length:  32
k_service:  a0b2fb2efe1977349c647d28e86d373aaa67ca9f452c15c7cfbdb9a4fabd685b of length:  32
k_signing:  e02df2af0ce8890816c931c8e72168921f5f481dfbcaf92a35324b65fc322865 of length:  32
sign_result:  3be60989db53028ca485b46a07df9287a1731df74a234ea247a99febb7c2eb31

Check out similar posts by category: Python, S3