

# Cálculos de firma para el encabezado de Authorization: transferencia de la carga útil en varios fragmentos (carga fragmentada) (AWS Signature Version 4)
<a name="sigv4-streaming"></a>

Como se describe en [Descripción general](sigv4-auth-using-authorization-header.md#sigv4-auth-header-overview), 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](#example-signature-calculations-streaming)) 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 encabezado `Transfer-Encoding` y especifica cualquier otro valor que no sea `identity`, debe omitir el encabezado `Content-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:

 

1. 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.

1. Cree la firma inicial para incluirla en el primer fragmento. Para obtener más información, consulte [Cálculo de la firma inicial](#sigv4-chunked-upload-sig-calculation-chunk0).

1. Cree el primer fragmento y transmítalo. Para obtener más información, consulte [Definición del cuerpo del fragmento](#sigv4-chunked-body-definition).

1. 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](#sigv4-chunked-body-definition).

1. 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](#sigv4-chunked-body-definition).

## Cálculo de la firma inicial
<a name="sigv4-chunked-upload-sig-calculation-chunk0"></a>

En el diagrama siguiente, se ilustra el proceso de cálculo de la firma inicial.

 

![El proceso de cálculo de la firma inicial.](https://docs.aws.amazon.com/es_es/AmazonS3/latest/developerguide/images/sigV4-auth-header-chunked-seed-signature.png)


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:+  El URI codifica todos los bytes excepto los caracteres no reservados: “A”-“Z”, “a”-“z”, “0”-“9”, “-”, “.”, “\_” y “\~”.  <br />+ El carácter de espacio es un carácter reservado y debe codificarse como “%20” (y no como “\+”). <br />+ Cada byte codificado en URI se encuentra formado por un “%” y el valor hexadecimal de dos dígitos del byte. <br />+ Las letras del valor hexadecimal deben estar en mayúsculas, por ejemplo, “%1A”. <br />+ Codifique el carácter de barra diagonal, “/”, en todas partes excepto en el nombre de la clave del objeto. Por ejemplo, si el nombre de la clave del objeto es `photos/Jan/sample.jpg`, la barra diagonal del nombre de la clave no se encuentra codificada.  Es 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. <br />A continuación, se muestra una función UriEncode() de ejemplo en Java.<pre>public static String UriEncode(CharSequence input, boolean encodeSlash) {<br />          StringBuilder result = new StringBuilder();<br />          for (int i = 0; i < input.length(); i++) {<br />              char ch = input.charAt(i);<br />              if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') {<br />                  result.append(ch);<br />              } else if (ch == '/') {<br />                  result.append(encodeSlash ? "%2F" : ch);<br />              } else {<br />                  result.append(toHexUTF8(ch));<br />              }<br />          }<br />          return result.toString();<br />      }</pre> | 

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)](sig-v4-header-based-auth.md). 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:


<table>
<thead>
  <tr><th>Encabezado</th><th>Descripción</th></tr>
</thead>
<tbody>
  <tr><td><code>x-amz-content-sha256</code></td><td>Este encabezado es obligatorio para todas las solicitudes de AWS Signature Version 4. Establezca el valor en <code>STREAMING-AWS4-HMAC-SHA256-PAYLOAD</code> para indicar que la firma solo cubre los encabezados y que no hay carga útil.</td></tr>
  <tr><td><code>Content-Encoding</code></td><td>Establezca el valor en <code>aws-chunked</code>. <br />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.<br />Por ejemplo:<pre>Content-Encoding : aws-chunked,gzip</pre><br />Amazon S3 almacena el objeto resultante sin el valor <code>aws-chunked</code> en el encabezado <code>content-encoding</code>. Si <code>aws-chunked</code> es el único valor que se pasa en el encabezado <code>content-encoding</code>, S3 considera el encabezado <code>content-encoding</code> vacío y no lo devuelve cuando se recupera el objeto. </td></tr>
  <tr><td><code>x-amz-decoded-content-length</code></td><td> Establezca 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).</td></tr>
  <tr><td><code>Content-Length</code></td><td>Establezca el valor en el tamaño real del cuerpo HTTP transmitido, que incluye la longitud de los datos (valor establecido para <code>x-amz-decoded-content-length</code>) 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 encabezado <code>Transfer-Encoding</code> y especifica cualquier otro valor que no sea <code>identity</code>, no debe incluir el encabezado <code>Content-Length</code>.</td></tr>
</tbody>
</table>


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
<a name="sigv4-chunked-body-definition"></a>

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 fragmento}} es 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.
+ {{Firma}} Para 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 proceso de calcular la firma inicial muestra los distintos componentes de la cadena que se va a firmar.](https://docs.aws.amazon.com/es_es/AmazonS3/latest/developerguide/images/sigV4-auth-header-chunk-signature.png)



 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
<a name="example-signature-calculations-streaming"></a>

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.


<table>
<thead>
  <tr><th>Parámetro</th><th>Valor</th></tr>
</thead>
<tbody>
  <tr><td><code>AWSAccessKeyId</code></td><td><code>AKIAIOSFODNN7EXAMPLE</code></td></tr>
  <tr><td><code>AWSSecretAccessKey</code></td><td><code>wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY</code></td></tr>
</tbody>
</table>

+ Todos los ejemplos utilizan la marca temporal de la solicitud 20130524T000000Z (`Fri, 24 May 2013 00:00:00 GMT`).
+ Todos los ejemplos utilizan `examplebucket` como nombre del bucket.
+ Se supone que el bucket está en la región Este de EE. UU. (Norte de Virginia) y la credencial `Scope` y los cálculos de `Signing Key` utilizan `us-east-1` como especificador de región. Para obtener más información, consulte [Regiones y puntos de enlace](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) 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.jpg
  ```

  Para obtener más información, consulte [Alojamiento virtual de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) 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_REDUNDANCY` como clase de almacenamiento, agregue el encabezado de solicitud `x-amz-storage-class`.

Para obtener información acerca de la acción de la API, consulte [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html). 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: {{SignatureToBeCalculated}}
x-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.

1. 

**Firma inicial: cree una cadena para firmar**

   1. 

**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-PAYLOAD
      ```

      En 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`.

   1. 

**StringToSign**

       

      ```
      AWS4-HMAC-SHA256
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455
      ```

       

       
**nota**  
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.

1. 

**SigningKey**

    

   ```
   signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "{{<YourSecretAccessKey>}}","20130524"),"us-east-1"),"s3"),"aws4_request")						
   ```

    

1. 

**Firma inicial**

    

   ```
   4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9
   ```

    

1. 

**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
   ```

    

1. 

**Fragmento 1: (65 536 bytes, con un valor de 97 para la letra “a”)**

   1. Cadena de fragmentos para firmar:

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a
      ```

       
**nota**  
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("")` y `hash(current-chunk-data)`).

   1. Firma de fragmentos:

      ```
      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
      ```

   1. Datos de fragmentos enviados:

      ```
      10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
      <65536-bytes>
      ```

1. 

**Fragmento 2: (1024 bytes, con un valor de 97 para la letra “a”)**

   1. Cadena de fragmentos para firmar:

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
      ```

   1. Firma de fragmentos:

      ```
      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
      ```

   1. Datos de fragmentos enviados:

      ```
      400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
      <1024 bytes>
      ```

1. 

**Fragmento 3: (datos de 0 bytes)**

   1. Cadena de fragmentos para firmar:

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      ```

   1. Firma de fragmentos:

      ```
      b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
      ```

   1. Datos de fragmentos enviados:

      ```
      0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
      ```