Cálculos de firma para el encabezado de Authorization: transferencia de la carga útil en varios fragmentos (carga fragmentada) (AWS Signature Version 4)
Como se describe en Descripción general, al autenticar las solicitudes mediante el encabezado Authorization, tiene una opción de cargar la carga útil en fragmentos. Puede enviar datos en fragmentos de tamaño fijo o de tamaño variable. En esta sección, se describe el proceso de cálculo de firmas en la carga fragmentada, cómo se crea el cuerpo del fragmento y cómo funciona la firma diferida cuando se carga el fragmento por primera vez y se envía su firma en el fragmento siguiente. La sección de ejemplos (consulte Ejemplo: objeto PUT) muestra los cálculos de firma y los encabezados Authorization resultantes que puede utilizar como conjunto de pruebas para verificar el código.
nota
Al transferir datos en una serie de fragmentos, debe realizar una de estas acciones:
-
Especifique de forma explícita la longitud total del contenido (longitud del objeto en bytes más los metadatos de cada fragmento) mediante el encabezado HTTP
Content-Length. Para ello, debe calcular previamente la longitud total de la carga útil, incluidos los metadatos que envíe en cada fragmento, antes de iniciar la solicitud. -
Especifique el encabezado HTTP
Transfer-Encoding. Si incluye el encabezadoTransfer-Encodingy especifica cualquier otro valor que no seaidentity, debe omitir el encabezadoContent-Length.
Para todas las solicitudes, debe incluir el encabezado x-amz-decoded-content-length, especificando el tamaño del objeto en bytes.
El cálculo de la firma de cada fragmento incluye la firma del fragmento anterior. Para empezar, debe crear una firma inicial utilizando solo los encabezados. La firma inicial se utiliza en el cálculo de la firma del primer fragmento. Para cada fragmento subsiguiente, se crea una firma de fragmento que incluye la firma del fragmento anterior. Por lo tanto, las firmas de los fragmentos se encadenan entre sí; es decir, la firma del fragmento n es una función F(fragmento n, firma[fragmento n-1]). El encadenamiento garantiza que envíe los fragmentos en el orden correcto.
Para realizar una carga fragmentada, haga lo siguiente:
-
Decida el tamaño del fragmento de carga útil. Lo necesita cuando escriba el código.
El tamaño del fragmento debe ser de al menos 8 KB. Recomendamos un tamaño de fragmento de al menos 64 KB para obtener un mejor rendimiento. Este tamaño de fragmento se aplica a todos los fragmentos excepto al último. El último fragmento que envíe puede tener un tamaño inferior a 8 KB. Si la carga útil es pequeña y cabe en un solo fragmento, puede ser inferior a los 8 KB.
-
Cree la firma inicial para incluirla en el primer fragmento. Para obtener más información, consulte Cálculo de la firma inicial.
-
Cree el primer fragmento y transmítalo. Para obtener más información, consulte Definición del cuerpo del fragmento.
-
Para cada fragmento subsiguiente, calcule la firma del fragmento que incluye la firma anterior en la cadena que firme, cree el fragmento y envíelo. Para obtener más información, consulte Definición del cuerpo del fragmento.
-
Envíe el último fragmento adicional, que es el mismo que los demás fragmentos de la creación, pero tiene cero bytes de datos. Para obtener más información, consulte Definición del cuerpo del fragmento.
Cálculo de la firma inicial
En el diagrama siguiente, se ilustra el proceso de cálculo de la firma inicial.
En la siguiente tabla, se describen las funciones que se muestran en el diagrama. Debe implementar código para estas funciones.
| Función | Descripción |
|---|---|
Lowercase() |
Convierta la cadena de caracteres en minúsculas. |
Hex() |
Codificación en minúsculas en base 16. |
SHA256Hash() |
Función de hash criptográfico del algoritmo de hash seguro (SHA). |
HMAC-SHA256() |
Calcula el HMAC mediante el algoritmo SHA256 con la clave de firma proporcionada. Esta es la firma final. |
Trim() |
Elimine cualquier espacio en blanco inicial o final. |
UriEncode() |
El URI codifica cada byte. UriEncode() debe aplicar las siguientes reglas:
importanteEs posible que las funciones estándar de UriEncode que proporciona su plataforma de desarrollo no funcionen debido a las diferencias en la implementación y a la ambigüedad relacionada en las RFC subyacentes. Le recomendamos que escriba su propia función UriEncode personalizada para asegurarse de que la codificación funcione. A continuación, se muestra una función UriEncode() de ejemplo en Java.
|
Para obtener información sobre el proceso de firma, consulte Cálculos de firma para el encabezado de Authorization: transferencia de la carga útil en un solo fragmento (AWS Signature Version 4). El proceso es el mismo, excepto que la creación de CanonicalRequest difiere de la siguiente manera:
-
Además de los encabezados de solicitud que planee agregar, debe incluir los siguientes encabezados:
Encabezado Descripción x-amz-content-sha256Este encabezado es obligatorio para todas las solicitudes de AWS Signature Version 4. Establezca el valor en
STREAMING-AWS4-HMAC-SHA256-PAYLOADpara indicar que la firma solo cubre los encabezados y que no hay carga útil.Content-EncodingEstablezca el valor en
aws-chunked.Amazon S3 admite varios valores de codificación de contenido. Puede especificar la codificación de contenido personalizada cuando utilice la API de streaming de Signature Version 4.
Por ejemplo:
Content-Encoding : aws-chunked,gzipAmazon S3 almacena el objeto resultante sin el valor
aws-chunkeden el encabezadocontent-encoding. Siaws-chunkedes el único valor que se pasa en el encabezadocontent-encoding, S3 considera el encabezadocontent-encodingvacío y no lo devuelve cuando se recupera el objeto.x-amz-decoded-content-lengthEstablezca el valor en la longitud, en bytes, de los datos que se van a fragmentar, sin contar ningún metadato. Por ejemplo, si va a cargar un archivo de 4 GB, establezca el valor en 4294967296. Este es el tamaño original del objeto que se va a cargar (datos que desea almacenar en Amazon S3). Content-LengthEstablezca el valor en el tamaño real del cuerpo HTTP transmitido, que incluye la longitud de los datos (valor establecido para
x-amz-decoded-content-length) y los metadatos de los fragmentos. Cada fragmento tiene metadatos, como la firma del fragmento anterior. Los cálculos de fragmentos se analizan en la siguiente sección. Si incluye el encabezadoTransfer-Encodingy especifica cualquier otro valor que no seaidentity, no debe incluir el encabezadoContent-Length.
Se envía el primer fragmento con la firma inicial. Debe crear el fragmento como se describe en la siguiente sección.
Definición del cuerpo del fragmento
Todos los fragmentos incluyen algunos metadatos. Cada fragmento debe cumplir la siguiente estructura:
string(IntHexBase(chunk-size)) + ";chunk-signature=" +signature+ \r\n +chunk-data+ \r\n
Donde:
-
IntHexBase()es una función que se escribe para convertir el tamaño de un fragmento entero en hexadecimal. Por ejemplo, si el tamaño del fragmento es 65536, la cadena hexadecimal es “10 000”. -
Tamaño de fragmentoes el tamaño, en bytes, de los datos del fragmento, sin metadatos. Por ejemplo, si carga un objeto de 65 KB y utiliza un tamaño de fragmento de 64 KB, carga los datos en tres fragmentos: el primero sería de 64 KB, el segundo de 1 KB y el último fragmento de 0 bytes. -
FirmaPara cada fragmento, se calcula la firma con la siguiente cadena para firmar. Para el primer fragmento, se utiliza la firma inicial como la firma anterior.
El tamaño de los últimos datos de fragmento que envíe es 0, aunque el cuerpo del fragmento aún contiene metadatos, incluida la firma del fragmento anterior.
Ejemplo: objeto PUT
Puede utilizar los ejemplos en esta sección como referencia para comprobar los cálculos de firma en el código. Antes de revisar los ejemplos, tenga en cuenta lo siguiente:
-
Los cálculos de firma de estos ejemplos utilizan las siguientes credenciales de seguridad de ejemplo.
Parámetro Valor AWSAccessKeyIdAKIAIOSFODNN7EXAMPLEAWSSecretAccessKeywJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -
Todos los ejemplos utilizan la marca temporal de la solicitud 20130524T000000Z (
Fri, 24 May 2013 00:00:00 GMT). -
Todos los ejemplos utilizan
examplebucketcomo nombre del bucket. -
Se supone que el bucket está en la región Este de EE. UU. (Norte de Virginia) y la credencial
Scopey los cálculos deSigning Keyutilizanus-east-1como especificador de región. Para obtener más información, consulte Regiones y puntos de enlace en la Referencia general de Amazon Web Services. -
Puede utilizar solicitudes de tipo ruta o de alojamiento virtual. Los ejemplos siguientes usan solicitudes de tipo de alojamiento virtual, por ejemplo:
https://examplebucket.s3.amazonaws.com/photos/photo1.jpgPara obtener más información, consulte Alojamiento virtual de buckets en la Guía del usuario de Amazon Simple Storage Service.
En el siguiente ejemplo, se envía una solicitud PUT para cargar un objeto. Los cálculos de firma suponen lo siguiente:
-
Está cargando un archivo de texto de 65 KB y el contenido del archivo es una cadena de un carácter compuesta por la letra “а”.
-
El tamaño del fragmento es 64 KB. Como resultado, la carga útil se carga en tres fragmentos: 64 KB, 1 KB y el fragmento final con 0 bytes de datos de fragmento.
-
El objeto resultante tiene el nombre de clave
chunkObject.txt. -
Para solicitar
REDUCED_REDUNDANCYcomo clase de almacenamiento, agregue el encabezado de solicitudx-amz-storage-class.
Para obtener información acerca de la acción de la API, consulte PutObject. La sintaxis de solicitud general es la siguiente:
PUT /examplebucket/chunkObject.txt HTTP/1.1 Host: s3.amazonaws.com x-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY Authorization:SignatureToBeCalculatedx-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD Content-Encoding: aws-chunked x-amz-decoded-content-length: 66560 Content-Length: 66824<Payload>
Los pasos siguientes muestran cálculos de firma.
-
Firma inicial: cree una cadena para firmar
-
CanonicalRequest
PUT /examplebucket/chunkObject.txt content-encoding:aws-chunked content-length:66824 host:s3.amazonaws.com x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD x-amz-date:20130524T000000Z x-amz-decoded-content-length:66560 x-amz-storage-class:REDUCED_REDUNDANCY content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class STREAMING-AWS4-HMAC-SHA256-PAYLOADEn la solicitud canónica, la tercera línea se encuentra vacía porque no hay parámetros de consulta en la solicitud. La última línea es la cadena constante proporcionada como valor de la carga útil con hash, que debe ser igual al valor de
x-amz-content-sha256 header. -
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455nota
Para obtener información sobre cada una de las líneas de la cadena que se va a firmar, consulte el diagrama que explica el cálculo de la firma inicial.
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Firma inicial
4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 -
Encabezado Authorization
El encabezado de Authorization resultante es el siguiente:
AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 -
Fragmento 1: (65 536 bytes, con un valor de 97 para la letra “a”)
-
Cadena de fragmentos para firmar:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5anota
Para obtener información sobre cada línea de la cadena que se va a firmar, consulte el diagrama anterior, que muestra los distintos componentes de la cadena que se va a firmar (por ejemplo, las tres últimas líneas son
previous-signature,hash("")yhash(current-chunk-data)). -
Firma de fragmentos:
ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 -
Datos de fragmentos enviados:
10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 <65536-bytes>
-
-
Fragmento 2: (1024 bytes, con un valor de 97 para la letra “a”)
-
Cadena de fragmentos para firmar:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a -
Firma de fragmentos:
0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 -
Datos de fragmentos enviados:
400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 <1024 bytes>
-
-
Fragmento 3: (datos de 0 bytes)
-
Cadena de fragmentos para firmar:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -
Firma de fragmentos:
b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9 -
Datos de fragmentos enviados:
0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
-