

# Distribución de contenido privado con URL firmadas y cookies firmadas
<a name="PrivateContent"></a>

Muchas empresas que distribuyen contenido a través de Internet desean restringir el acceso a documentos, información corporativa, transmisiones multimedia o contenido destinado a una selección de usuarios; por ejemplo, a los usuarios que hayan pagado una determinada tarifa. Para ofrecer este contenido privado de forma segura a través de CloudFront, puede hacer lo siguiente:
+ Solicite que los usuarios accedan al contenido privado mediante URL firmadas o cookies firmadas especiales de CloudFront. 
+ Solicite que los usuarios accedan al contenido a través de URL de CloudFront, no URL que accedan al contenido directamente en el servidor de origen (por ejemplo, Amazon S3 o un servidor HTTP privado). No es necesario solicitar URL de CloudFront, pero lo recomendamos para impedir que los usuarios eludan las restricciones que especifique en URL firmadas o cookies firmadas.

Para obtener más información, consulte [Restricción del acceso a archivos](private-content-overview.md).

## Distribución de contenido privado
<a name="private-content-task-list"></a>

Para configurar CloudFront para que distribuya contenido privado, realice las siguientes tareas:

1. Solicite a los usuarios que accedan al contenido solo a través de CloudFront (opcional pero recomendado). El método que utilice depende de si utiliza Amazon S3 u orígenes personalizados:
   + **Amazon S3**: consulte [Restricción del acceso a un origen de Amazon S3](private-content-restricting-access-to-s3.md).
   + **Origen personalizado**: consulte [Restricción del acceso a archivos en orígenes personalizados](private-content-overview.md#forward-custom-headers-restrict-access).

   Los orígenes personalizados incluyen Amazon EC2, buckets de Amazon S3 configurados como puntos de enlace del sitio web, Elastic Load Balancing y sus propios servidores web HTTP.

1. Especifique los *grupos de claves de confianza* o los *signatarios de confianza* que desea utilizar para crear URL firmadas o cookies firmadas. Le recomendamos que utilice grupos de claves de confianza. Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

1. Escriba la aplicación para responder a las solicitudes de los usuarios autorizados con URL firmadas o con encabezados `Set-Cookie` que establezcan cookies firmadas. Siga los pasos en uno de los siguientes temas: 
   + [Uso de URL firmadas](private-content-signed-urls.md)
   + [Uso de cookies firmadas](private-content-signed-cookies.md)

   Si no está seguro de qué método utilizar, consulte [Decisión de utilizar URL firmadas o cookies firmadas](private-content-choosing-signed-urls-cookies.md).

**Topics**
+ [Distribución de contenido privado](#private-content-task-list)
+ [Restricción del acceso a archivos](private-content-overview.md)
+ [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md)
+ [Decisión de utilizar URL firmadas o cookies firmadas](private-content-choosing-signed-urls-cookies.md)
+ [Uso de URL firmadas](private-content-signed-urls.md)
+ [Uso de cookies firmadas](private-content-signed-cookies.md)
+ [Comandos de Linux y OpenSSL para codificación y cifrado base64](private-content-linux-openssl.md)
+ [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md)

# Restricción del acceso a archivos
<a name="private-content-overview"></a>

Puede controlar el acceso de los usuarios al contenido privado de dos maneras:
+ [Restringir el acceso a los archivos en las cachés de CloudFront](#private-content-overview-edge-caches).
+ Restrinja el acceso a los archivos en su origen de la siguiente manera:
  + [Configure un control de acceso de origen (OAC) para su bucket de Amazon S](private-content-restricting-access-to-s3.md).
  + [Configure encabezados personalizados para un servidor HTTP privado (un origen personalizado)](#forward-custom-headers-restrict-access).

## Restricción del acceso a archivos en las cachés de CloudFront
<a name="private-content-overview-edge-caches"></a>

Puede configurar CloudFront para que solicite que los usuarios accedan a los archivos mediante *URL firmadas* o *cookies firmadas*. Después, deberá desarrollar la aplicación para crear y distribuir URL firmadas para los usuarios autenticados o para enviar encabezados `Set-Cookie` que establecen cookies firmadas para usuarios autenticados. (También puede crear URL firmadas manualmente para ofrecer a unos pocos usuarios acceso largo plazo a un número reducido de archivos). 

Si crea URL o cookies firmadas para controlar el acceso a sus archivos, puede especificar las siguientes restricciones:
+ La fecha y la hora de finalización, a partir de la cual la URL deja de ser válida. 
+ La fecha y la hora a la que la URL pasa a ser válida (opcional).
+ La dirección IP o a un rango de direcciones IP de los equipos desde los que se puede obtener acceso a su contenido. 

A una parte de una URL firmada o una cookie firmada se le aplica el algoritmo hash y se firma con la clave privada de un par de claves públicas-privadas. Cuando alguien utiliza una URL firmada o una cookie firmada para acceder a un archivo, CloudFront compara las partes firmadas y sin firmar de la URL o de la cookie. Si no coinciden, CloudFront no envía el archivo.

Debe utilizar claves privadas RSA 2048 o ECDSA 256 para firmar URL o cookies.

## Restricción del acceso a archivos en buckets de Amazon S3
<a name="private-content-overview-s3"></a>

Si lo desea, puede proteger el contenido de su bucket de Amazon S3 para que los usuarios puedan acceder a él a través de la distribución de CloudFront especificada, pero no puedan acceder directamente mediante las URL de Amazon S3. Esto evita que se eluda CloudFront y se use la URL de Amazon S3 para obtener el contenido cuyo acceso desea restringir. Este paso no es necesario para utilizar URL firmadas, pero recomendamos seguirlo.

Para solicitar que los usuarios accedan al contenido a través de URL de CloudFront, realice las siguientes tareas:
+ Conceder un permiso de *control de acceso de origen* de CloudFront para leer los archivos del bucket de S3.
+ Crear el control de acceso de origen y asociarlo con su distribución de CloudFront.
+ Quite a todos los demás el permiso para usar URL de Amazon S3 para leer los archivos.

Para obtener más información, consulte [Restricción del acceso a un origen de Amazon S3](private-content-restricting-access-to-s3.md).

## Restricción del acceso a archivos en orígenes personalizados
<a name="forward-custom-headers-restrict-access"></a>

Si utiliza un origen personalizado, tiene la opción de configurar encabezados personalizados para restringir el acceso. Para que CloudFront obtenga los archivos de un origen personalizado, debe ser posible el acceso de CloudFront a los archivos mediante una solicitud HTTP estándar (o HTTPS). Sin embargo, mediante el uso de encabezados personalizados, puede restringir aún más el acceso al contenido para que los usuarios puedan acceder al mismo solo a través de CloudFront, no directamente. Este paso no es necesario para utilizar URL firmadas, pero recomendamos seguirlo.

Para solicitar que los usuarios accedan al contenido a través de CloudFront, cambie la siguiente configuración de las distribuciones de CloudFront:

**Encabezados personalizados de origen**  
Configure CloudFront para reenviar encabezados personalizados al origen. Consulte [Configuración de CloudFront para agregar encabezados personalizados a solicitudes de origen](add-origin-custom-headers.md#add-origin-custom-headers-configure).

**Viewer Protocol Policy**  
Configure la distribución para solicitar a los lectores que utilicen HTTPS para acceder a CloudFront. Consulte [Política de protocolo para lectores](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy). 

**Origin Protocol Policy**  
Configure la distribución para solicitar a CloudFront que utilice el mismo protocolo que los lectores para reenviar solicitudes al origen. Consulte [Protocolo (solo orígenes personalizados)](DownloadDistValuesOrigin.md#DownloadDistValuesOriginProtocolPolicy). 

Después de haber realizado estos cambios, actualice la aplicación en el origen personalizado para aceptar solo solicitudes que incluyan los encabezados personalizados que ha configurado para que CloudFront los envíe.

La combinación de **Viewer Protocol Policy (Política de protocolo del lector)** y **Origin Protocol Policy (Política de protocolo de origen)** garantiza que los encabezados personalizados se cifren en tránsito. Sin embargo, le recomendamos realizar periódicamente las siguientes acciones para rotar los encabezados personalizados que CloudFront reenvía al origen:

1. Actualice la distribución de CloudFront para comenzar a reenviar un nuevo encabezado al origen personalizado.

1. Actualice la aplicación para aceptar el nuevo encabezado a modo de confirmación de que la solicitud proviene de CloudFront.

1. Cuando las solicitudes ya no incluyan el encabezado que ha reemplazado, actualice la aplicación para que ya no acepte el encabezado anterior a modo de confirmación de que la solicitud proviene de CloudFront.

# Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas
<a name="private-content-trusted-signers"></a>

**Topics**
+ [Elección entre grupos de claves de confianza (recomendado) y Cuentas de AWS](#choosing-key-groups-or-AWS-accounts)
+ [Creación de pares de claves para los firmantes](#private-content-creating-cloudfront-key-pairs)
+ [Volver a formatear la clave privada (solo .NET y Java)](#private-content-reformatting-private-key)
+ [Agregación de un firmante a una distribución](#private-content-adding-trusted-signers)
+ [Rotación de pares de claves](#private-content-rotating-key-pairs)

Para crear URL firmadas o cookies firmadas, necesita un *signatario*. Un signatario es un grupo de claves de confianza que se crea en CloudFront o una cuenta de AWS que contiene un par de claves de CloudFront. Le recomendamos que utilice grupos de claves de confianza con URL firmadas y cookies firmadas. Para obtener más información, consulte [Elección entre grupos de claves de confianza (recomendado) y Cuentas de AWS](#choosing-key-groups-or-AWS-accounts).

El signatario tiene dos fines:
+ Tan pronto como agregue el signatario a la distribución, CloudFront comienza a requerir que los lectores utilicen URL firmadas o cookies firmadas para acceder a los archivos.
+ Al crear URL firmadas o cookies firmadas, se utiliza la clave privada del par de claves del signatario para firmar una parte de la URL o la cookie. Cuando alguien solicita un archivo restringido, CloudFront compara la firma de la URL o la cookie con la URL o la cookie sin firmar, para verificar que no se ha manipulado. CloudFront también verifica que la URL o la cookie sean válidas, es decir, por ejemplo, que la fecha y la hora de vencimiento no han pasado todavía.

Cuando se especifica un signatario, también se especifican indirectamente los archivos que requieren URL firmadas o cookies firmadas al agregar el signatario a un comportamiento de la caché. Si la distribución solo dispone de un comportamiento de la caché, los lectores deben utilizar URL o cookies firmadas para acceder a cualquier archivo de la distribución. Si crea varios comportamientos de la caché y agrega signatarios a algunos de ellos pero no a otros, puede exigir que los lectores utilicen URL o cookies firmadas para acceder a algunos archivos y no a otros.

Para especificar los signatarios (las claves privadas) autorizados para crear URL firmadas o cookies firmadas y para agregar los signatarios a la distribución de CloudFront, realice las siguientes tareas:

1. Decida si desea utilizar un grupo de claves de confianza o una Cuenta de AWS como firmante. Recomendamos utilizar un grupo de claves de confianza. Para obtener más información, consulte [Elección entre grupos de claves de confianza (recomendado) y Cuentas de AWS](#choosing-key-groups-or-AWS-accounts).

1. Para el signatario que eligió en el paso 1, cree un par de claves privadas-públicas. Para obtener más información, consulte [Creación de pares de claves para los firmantes](#private-content-creating-cloudfront-key-pairs).

1. Si utiliza .NET o Java para crear URL firmadas o cookies firmadas, vuelva a formatear la clave privada. Para obtener más información, consulte [Volver a formatear la clave privada (solo .NET y Java)](#private-content-reformatting-private-key).

1. En la distribución para la que va a crear URL firmadas o cookies firmadas, especifique el signatario. Para obtener más información, consulte [Agregación de un firmante a una distribución](#private-content-adding-trusted-signers).

## Elección entre grupos de claves de confianza (recomendado) y Cuentas de AWS
<a name="choosing-key-groups-or-AWS-accounts"></a>

Para utilizar URL firmadas o cookies firmadas, necesita un *signatario*. Un firmante es un grupo de claves de confianza que se crea en CloudFront o una Cuenta de AWS que contiene un par de claves de CloudFront. Se recomienda utilizar grupos de claves de confianza, por los siguientes motivos:
+ Con los grupos de claves de CloudFront no es necesario usar el usuario raíz de la cuenta de AWS para administrar las claves públicas de las URL firmadas y las cookies firmadas de CloudFront. Las [prácticas recomendadas de AWS](https://docs.aws.amazon.com/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root) indican no utilizar el usuario raíz cuando no es necesario.
+ Con los grupos de claves de CloudFront, puede administrar claves públicas, grupos de claves y signatarios de confianza mediante la API de CloudFront. Puede usar la API para automatizar la creación de claves y la rotación de claves. Cuando se utiliza el usuario raíz de AWS, se debe utilizar la Consola de administración de AWS para administrar pares de claves de CloudFront, de modo que no se puede automatizar el proceso.
+ Dado que puede administrar grupos de claves con la API de CloudFront, también puede utilizar las políticas de permisos de AWS Identity and Access Management (IAM) para limitar lo que los distintos usuarios pueden hacer. Por ejemplo, puede permitir a los usuarios cargar claves públicas, pero no eliminarlas. También puede permitir que los usuarios eliminen claves públicas, pero solo cuando se cumplen ciertas condiciones, como el uso de la autenticación multifactor, el envío de la solicitud desde una red determinada o el envío de la solicitud dentro de un intervalo de fecha y hora determinado.
+ Con los grupos de claves de CloudFront, puede asociar un número mayor de claves públicas con la distribución de CloudFront, lo que le concede más flexibilidad en la forma de usar y administrar las claves públicas. De forma predeterminada, puede asociar hasta cuatro grupos de claves con una sola distribución y puede tener hasta cinco claves públicas en un grupo de claves.

  Cuando utiliza el usuario raíz de la cuenta de AWS para administrar pares de claves de CloudFront, solo puede tener hasta dos pares de claves activos de CloudFront por cuenta de AWS.

## Creación de pares de claves para los firmantes
<a name="private-content-creating-cloudfront-key-pairs"></a>

Cada signatario que utilice para crear URL firmadas o cookies firmadas de CloudFront debe tener un par de claves públicas-privadas. El signatario utiliza la clave privada para firmar la URL o las cookies y CloudFront utiliza la clave pública para comprobar la firma.

La forma en que se crea un par de claves depende de si se utiliza un grupo de claves de confianza como el signatario (recomendado) o un par de claves de CloudFront. Para obtener más información, consulte las siguientes secciones. El par de claves que cree debe cumplir los siguientes requisitos:
+ Debe ser un par de claves SSH-2 RSA 2048 o ECDSA 256.
+ Debe encontrarse en formato PEM codificado en Base64.

Para ayudar a proteger las aplicaciones, le recomendamos que cambie los pares de claves periódicamente. Para obtener más información, consulte [Rotación de pares de claves](#private-content-rotating-key-pairs).

### Crear un par de claves para un grupo de claves de confianza (recomendado)
<a name="create-key-pair-and-key-group"></a>

Para crear un par de claves para un grupo de claves de confianza, realice los siguientes pasos:

1. Cree el par de claves públicas-privadas.

1. Cargue la clave pública en CloudFront.

1. Agregue la clave pública a un grupo de claves de CloudFront.

Para obtener más información, consulte los siguientes procedimientos.<a name="private-content-uploading-cloudfront-public-key-procedure"></a>

**Para crear un par de claves**
**nota**  
En los siguientes pasos se utiliza OpenSSL como ejemplo de un método para crear un par de claves. Hay muchas otras formas de crear un par de claves RSA o ECDSA.

1. Ejecute uno de los siguientes comandos de ejemplo:
   + El siguiente comando de ejemplo utiliza OpenSSL para generar un par de claves RSA con una longitud de 2048 bits y guardarlo en el archivo denominado `private_key.pem`.

     ```
     openssl genrsa -out private_key.pem 2048
     ```
   + El siguiente comando de ejemplo utiliza OpenSSL para generar un par de claves ECDSA con la curva `prime256v1` y guárdelo en el archivo denominado `private_key.pem`.

     ```
     openssl ecparam -name prime256v1 -genkey -noout -out privatekey.pem
     ```

1. El archivo resultante contiene tanto la clave pública como la privada. El siguiente comando de ejemplo extrae la clave pública del archivo denominado `private_key.pem`.

   ```
   openssl rsa -pubout -in private_key.pem -out public_key.pem
   ```

   Se carga la clave pública (en el archivo `public_key.pem`) más adelante, en el siguiente procedimiento.

**Para cargar la clave pública en CloudFront**

1. Inicie sesión en Consola de administración de AWS y abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. En el menú de navegación, elija **Claves públicas**.

1. Elija **Crear clave pública**.

1. En la ventana **Crear clave pública**, haga lo siguiente:

   1. En **Key name (Nombre de la clave)**, escriba un nombre para identificar la clave pública.

   1. En **Key value (Valor de clave)**, pegue la clave pública. Si ha seguido los pasos del procedimiento anterior, la clave pública se encuentra en el archivo denominado `public_key.pem`. Para copiar y pegar el contenido de la clave pública, puede:
      + Use el comando **cat** en la línea de comandos de macOS o Linux, así:

        ```
        cat public_key.pem
        ```

        Copie el resultado de ese comando y péguelo en el campo **Key value (Valor de clave)**.
      + Abra el archivo `public_key.pem` con un editor de texto sin formato como el Bloc de notas (en Windows) o TextEdit (en macOS). Copie el contenido del archivo y péguelo en el campo **Key value (Valor de clave)**.

   1. (Opcional) En **Comment (Comentario)**, agregue un comentario para describir la clave pública.

   Cuando haya terminado, elija **Add (Agregar)**.

1. Registre el ID de la clave pública. Lo usará más adelante cuando cree URL firmadas o cookies firmadas, como valor del campo `Key-Pair-Id`.

**Para agregar la clave pública a un grupo de claves**

1. Abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. En el menú de navegación, elija **Grupos de claves**.

1. Elija **Add key group (Agregar grupo de claves)**.

1. En la página **Create key group (Crear grupo de claves)**, haga lo siguiente:

   1. En **Key group name (Nombre del grupo de claves)**, escriba un nombre para identificar el grupo de claves.

   1. (Opcional) En **Comment (Comentario)**, escriba un comentario para describir el grupo de claves.

   1. En **Public keys (Claves públicas)**, seleccione la clave pública que desea agregar al grupo de claves y, a continuación, elija **Add (Agregar)**. Repita este paso para cada clave pública que desee agregar al grupo de claves.

1. Elija **Create key group (Crear grupo de claves)**.

1. Registre el nombre del grupo de claves. Se utiliza más adelante para asociar el grupo de claves con un comportamiento de la caché en una distribución de CloudFront. (En la API de CloudFront, se utiliza el ID del grupo de claves para asociar el grupo de claves con un comportamiento de la caché).

### Creación de un par de claves de CloudFront (no recomendado, se requiere el usuario raíz de la Cuenta de AWS)
<a name="create-key-pair-aws-account"></a>

**importante**  
Se recomienda crear una clave pública para un grupo de claves de confianza en lugar de seguir estos pasos. Para obtener información sobre la forma recomendada de crear claves públicas para URL firmadas y cookies firmadas, consulte [Crear un par de claves para un grupo de claves de confianza (recomendado)](#create-key-pair-and-key-group).

Puede crear un par de claves de CloudFront de las siguientes maneras:
+ Crear un par de claves en la Consola de administración de AWS y descargar la clave privada. Consulte el procedimiento siguiente.
+ Cree un par de claves RSA usando una aplicación como OpenSSL y, a continuación, cargue la clave pública en la Consola de administración de AWS. Para obtener más información acerca de la creación de un par de claves RSA, consulte [Crear un par de claves para un grupo de claves de confianza (recomendado)](#create-key-pair-and-key-group).<a name="private-content-creating-cloudfront-key-pairs-procedure"></a>

**Para crear pares de claves de CloudFront en la Consola de administración de AWS**

1. Inicie sesión en la Consola de administración de AWS con las credenciales del usuario raíz de la cuenta de AWS.
**importante**  
Los usuarios de IAM no pueden crear pares de claves de CloudFront. Debe iniciar sesión con credenciales de usuario raíz para crear pares de claves.

1. Elija el nombre de la cuenta y, a continuación, elija **My Security Credentials (Mis credenciales de seguridad)**.

1. Elija **CloudFront key pairs (Pares de claves de CloudFront)**.

1. Confirme que no tiene más de un par de claves activas. No se puede crear un par de claves si ya dispone de dos pares de claves activos.

1. Elija **Create New Key Pair (Crear un nuevo par de claves)**.
**nota**  
También puede elegir crear su propio par de claves y cargar la clave pública. Los pares de claves de CloudFront admiten claves de 1024, 2048 o 4096 bits.

1. En el cuadro de diálogo **Create Key Pair (Crear par de claves)**, elija **Download Private Key File (Descargar archivo de claves privadas)** y, a continuación, guarde el archivo en el equipo.
**importante**  
Guarde la clave privada del par de claves de CloudFront en un lugar seguro y establezca permisos en el archivo para que solo los administradores que usted decida puedan leerlo. Si alguien obtiene su clave privada, puede generar URL y cookies firmadas válidas y descargar su contenido. No podrá obtener la clave privada de nuevo, por lo que si la pierde o la elimina, deberá crear un nuevo par de claves de CloudFront.

1. Registre el ID de su par de claves. (En la Consola de administración de AWS, esto se denomina **Access Key ID [ID de clave de acceso]**). Lo utilizará al crear URL firmadas o cookies firmadas.

## Volver a formatear la clave privada (solo .NET y Java)
<a name="private-content-reformatting-private-key"></a>

Si utiliza .NET o Java para crear URL firmadas o cookies firmadas, no puede utilizar la clave privada del par de claves en el formato PEM predeterminado para crear la firma. En su lugar, haga lo siguiente:
+ **.NET framework**: convierte la clave privada en el formato XML que utiliza .NET Framework. Hay varias herramientas disponibles.
+ **Java**: convierte la clave privada en formato DER. Una forma de hacerlo es con el siguiente comando de OpenSSL. En el siguiente comando, `private_key.pem` es el nombre del archivo que contiene la clave privada con formato PEM y `private_key.der` es el nombre del archivo que contiene la clave privada con formato DER después de ejecutar el comando.

  ```
  openssl pkcs8 -topk8 -nocrypt -in private_key.pem -inform PEM -out private_key.der -outform DER
  ```

  Para asegurarse de que el codificador funciona correctamente, agregue el recurso JAR de la API de criptografía Java Bouncy Castle a su proyecto y, a continuación, agregue el proveedor Bouncy Castle.

## Agregación de un firmante a una distribución
<a name="private-content-adding-trusted-signers"></a>

Un signatario es el grupo de claves de confianza (recomendado) o el par de claves de CloudFront que puede crear URL firmadas y cookies firmadas para una distribución. Para utilizar URL firmadas o cookies firmadas con una distribución de CloudFront, debe especificar un signatario.

Los signatarios se asocian con comportamientos de la caché. Esto le permite exigir URL firmadas o cookies firmadas para algunos archivos y no para otros dentro de la misma distribución. Una distribución requiere URL o cookies firmadas solo para los archivos asociados con los comportamientos de la caché correspondientes.

Del mismo modo, un signatario solo puede firmar URL o cookies para archivos asociados con los comportamientos de la caché correspondientes. Por ejemplo, si tiene un signatario para un comportamiento de la caché y un signatario diferente para un comportamiento de la caché diferente, ninguno de los dos signatarios puede crear URL o cookies firmadas para los archivos asociados con el otro comportamiento de la caché.

**importante**  
Antes de agregar un signatario a la distribución, haga lo siguiente:  
Defina cuidadosamente los patrones de ruta y la secuencia de los comportamientos de la caché para no conceder a los usuarios acceso no deseado al contenido o impedir que accedan al contenido que desea que esté disponible para todos.  
Supongamos que una solicitud coincide con el patrón de ruta de dos comportamientos de la caché. El primer comportamiento de la caché no requiere URL firmadas ni cookies firmadas y el segundo comportamiento de la caché sí. Los usuarios podrán acceder a los archivos sin usar URL ni cookies firmadas porque CloudFront procesa el comportamiento de la caché que está asociado con la primera coincidencia.  
Para obtener más información acerca de patones de rutas, consulte [Patrón de ruta](DownloadDistValuesCacheBehavior.md#DownloadDistValuesPathPattern).
Para una distribución que ya utiliza para distribuir contenido, asegúrese de que está listo para comenzar a generar URL firmadas y cookies firmadas antes de agregar un signatario. Cuando se agrega un signatario, CloudFront rechaza las solicitudes que no incluyen una URL firmada o una cookie firmada válidas.

Puede agregar signatarios a la distribución utilizando la consola de CloudFront o la API de CloudFront.

------
#### [ Console ]

En los siguientes pasos se muestra cómo agregar un grupo de claves de confianza como signatario. También puede agregar una Cuenta de AWS como firmante de confianza, pero no es recomendable hacerlo.<a name="private-content-adding-trusted-signers-console-procedure"></a>

**Para agregar un signatario a una distribución mediante la consola**

1. Registre el ID del grupo de claves del grupo de claves que desea utilizar como signatario de confianza. Para obtener más información, consulte [Crear un par de claves para un grupo de claves de confianza (recomendado)](#create-key-pair-and-key-group).

1. Abra la consola de CloudFront en [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home).

1. Elija la distribución cuyos archivos desea proteger con URL firmadas o cookies firmadas.
**nota**  
Para agregar un signatario a una distribución nueva, se especifica la misma configuración que se describe en el paso 6 al crear la distribución.

1. Elija la pestaña **Behaviors (Comportamientos)**.

1. Seleccione el comportamiento de caché cuyo patrón de ruta coincida con los archivos que desea proteger con URL firmadas o cookies firmadas y, a continuación, elija **Edit (Editar)**.

1. En la página **Edit Behavior (Editar comportamiento)**, haga lo siguiente:

   1. En **Restrict Viewer Access (Use Signed URLs or Signed Cookies) (Restringir el acceso a lectores [mediante URL o cookies firmadas])**, elija **Yes (Sí)**.

   1. En **Trusted Key Groups or Trusted Signer (Grupos de claves de confianza o signatario de confianza)**, elija **Trusted Key Groups (Grupos de claves de confianza)**.

   1. En **Trusted Key Groups (Grupos de claves de confianza)**, elija el grupo de claves que desea agregar y, a continuación, elija **Add (Agregar)**. Repita el procedimiento si desea agregar más de un grupo de claves.

1. Elija **Yes, Edit (Sí, Editar)** para actualizar el comportamiento de la caché.

------
#### [ API ]

Puede usar la API de CloudFront para agregar un grupo de claves de confianza como signatario. Puede agregar un signatario a una distribución existente o a una distribución nueva. En cualquier caso, deberá especificar los valores en el elemento `TrustedKeyGroups`.

También puede agregar una Cuenta de AWS como firmante de confianza, pero no es recomendable hacerlo.

Consulte los siguientes temas en la *Referencia de la API de Amazon CloudFront*:
+ **Actualizar una distribución existente**: [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)
+ **Crear una nueva distribución**: [CreateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html)

------

## Rotación de pares de claves
<a name="private-content-rotating-key-pairs"></a>

Se recomienda rotar periódicamente (cambiar) los pares de claves para las URL firmadas y las cookies firmadas. Para rotar pares de claves que utiliza para crear URL firmadas o cookies firmadas sin invalidar las URL o cookies que no hayan vencido todavía, realice las siguientes tareas:

1. Cree un nuevo par de claves y agregue la clave pública a un grupo de claves. Para obtener más información, consulte [Crear un par de claves para un grupo de claves de confianza (recomendado)](#create-key-pair-and-key-group).

1. Si ha creado un nuevo grupo de claves en el paso anterior, [agregue el grupo de claves a la distribución como signatario](#private-content-adding-trusted-signers).
**importante**  
No elimine ninguna clave pública existente del grupo de claves ni ningún grupo de claves de la distribución todavía. Solo agregue los nuevos.

1. Actualice la aplicación para crear firmas con la clave privada del nuevo par de claves. Confirme que las URL firmadas o las cookies firmadas con las nuevas claves privadas funcionan.

1. Espere hasta que pase la fecha de vencimiento de las URL o las cookies firmadas con la clave privada anterior. A continuación, elimine la clave pública anterior del grupo de claves. Si ha creado un nuevo grupo de claves en el paso 2, elimine el grupo de claves anterior de la distribución.

# Decisión de utilizar URL firmadas o cookies firmadas
<a name="private-content-choosing-signed-urls-cookies"></a>

Las URL firmadas y las cookies firmadas de CloudFront proporcionan la misma funcionalidad básica: le permiten controlar quién puede obtener acceso al contenido. Si desea distribuir contenido privado a través de CloudFront e intenta decidir si utilizar URL firmadas o cookies firmadas, tenga en cuenta lo siguiente.

Utilice URL firmadas en los casos siguientes:
+ Si desea restringir el acceso a archivos individuales, por ejemplo, una descarga de instalación para su aplicación.
+ Si sus usuarios utilizan un cliente (por ejemplo, un cliente HTTP personalizado) que no admite cookies.

Utilice cookies firmadas en los casos siguientes:
+ Si desea proporcionar acceso a varios archivos restringidos (por ejemplo, a todos los archivos de un vídeo en formato HLS o a todos los archivos del área de suscriptores de un sitio web).
+ Si no quiere cambiar las URL actuales.

Si en la actualidad no utiliza URL firmadas y si sus URL (sin firmar) contienen cualquiera de los siguientes parámetros de cadenas de consulta, no puede utilizar cookies firmadas ni URL firmadas:
+ `Expires`
+ `Policy`
+ `Signature`
+ `Key-Pair-Id`

CloudFront asume que las URL que contienen cualquiera de los parámetros de cadenas de consulta son URL firmadas y, por lo tanto, no examina las cookies firmadas.

## Uso de URL firmadas y cookies firmadas
<a name="private-content-using-signed-urls-and-cookies"></a>

Las URL firmadas tienen prioridad sobre las cookies firmadas. Si utiliza URL firmadas y cookies firmadas para controlar el acceso a los mismos archivos y un lector utiliza una URL firmada para solicitar un archivo, CloudFront determina si debe devolver el objeto al lector basándose únicamente en la URL firmada.

# Uso de URL firmadas
<a name="private-content-signed-urls"></a>

Una URL firmada incluye información adicional, por ejemplo, una fecha y hora de vencimiento, lo que permite un mayor control sobre el acceso a su contenido. Esta información adicional aparece en una instrucción de política basada en una política predefinida o personalizada. Las diferencias entre las políticas personalizadas y las predefinidas se explican en las próximas dos secciones.

**nota**  
Puede crear algunas URL firmadas con políticas predefinidas y crear otras con políticas personalizadas para la misma distribución.

**Topics**
+ [Decisión de utilizar políticas predefinidas o personalizadas para URL firmadas](#private-content-choosing-canned-custom-policy)
+ [Cómo funcionan las URL firmadas](#private-content-how-signed-urls-work)
+ [Decisión del tiempo de validez de las URL firmadas](#private-content-overview-choosing-duration)
+ [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una URL firmada](#private-content-check-expiration)
+ [Código de ejemplo y herramientas de terceros](#private-content-overview-sample-code)
+ [Creación de una URL firmada mediante una política predefinida](private-content-creating-signed-url-canned-policy.md)
+ [Creación de una URL firmada mediante una política personalizada](private-content-creating-signed-url-custom-policy.md)

## Decisión de utilizar políticas predefinidas o personalizadas para URL firmadas
<a name="private-content-choosing-canned-custom-policy"></a>

Al crear una URL firmada, se escribe una instrucción de política en formato JSON que especifica las restricciones en la URL firmada, por ejemplo, el tiempo de validez de la URL. Puede utilizar una política predefinida o personalizada. A continuación, se presenta una comparación entre las políticas predefinidas y las personalizadas:


****  

| Descripción | Política predefinida | Política personalizada | 
| --- | --- | --- | 
| Puede reutilizar la instrucción de la política con varios archivos. Para reutilizar la instrucción de política, debe utilizar caracteres comodín en el objeto `Resource`. Para obtener más información, consulte [Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política personalizada](private-content-creating-signed-url-custom-policy.md#private-content-custom-policy-statement-values)).  | No | Sí | 
| Puede especificar la fecha y la hora a la que los usuarios pueden empezar a obtener acceso a su contenido. | No | Sí (opcional) | 
| Puede especificar la fecha y la hora a la que los usuarios dejan de obtener acceso a su contenido. | Sí | Sí | 
| Puede especificar la dirección IP o a un rango de direcciones IP de los usuarios que pueden obtener acceso a su contenido. | No | Sí (opcional) | 
| La URL firmada incluye una versión de la política con codificación de tipo base64, lo que resulta en una URL más larga. | No | Sí | 

Para obtener información acerca de cómo crear URL firmadas mediante una política *predefinida*, consulte [Creación de una URL firmada mediante una política predefinida](private-content-creating-signed-url-canned-policy.md).

Para obtener información acerca de cómo crear URL firmadas mediante una política *personalizada*, consulte [Creación de una URL firmada mediante una política personalizada](private-content-creating-signed-url-custom-policy.md).

## Cómo funcionan las URL firmadas
<a name="private-content-how-signed-urls-work"></a>

A continuación, se muestra información general de cómo se configura CloudFront y Amazon S3 para URL firmadas y cómo responde CloudFront cuando un usuario utiliza una URL firmada para solicitar un archivo. 

1. En la distribución de CloudFront, especifique uno o más grupos de claves de confianza, que contienen las claves públicas que CloudFront puede utilizar para comprobar la firma de URL. Se utilizan las claves privadas correspondientes para firmar las URL.

   CloudFront admite direcciones URL firmadas con firmas de claves RSA 2048 y ECDSA 256.

   Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

1. Desarrolle la aplicación para determinar si un usuario debe tener acceso al contenido y crear URL firmadas para los archivos o partes de la aplicación a las que desea restringir el acceso. Para obtener más información, consulte los siguientes temas:
   + [Creación de una URL firmada mediante una política predefinida](private-content-creating-signed-url-canned-policy.md)
   + [Creación de una URL firmada mediante una política personalizada](private-content-creating-signed-url-custom-policy.md)

1. Un usuario solicita un archivo que va a requerir URL firmadas.

1. La aplicación verifica si el usuario tiene derecho para obtener acceso al archivo: si ha iniciado sesión, si ha pagado por obtener acceso al contenido o si ha cumplido algún otro requisito para obtener acceso.

1. Su aplicación crea una URL firmada y la devuelve el usuario.

1. Las URL firmadas permiten al usuario descargar o transmitir el contenido.

   Este paso es automático; el usuario normalmente no tiene que hacer nada más para obtener acceso al contenido. Por ejemplo, si un usuario accede a su contenido desde un navegador web, la aplicación devuelve la URL firmada al navegador. El navegador utiliza inmediatamente la URL firmada para acceder al archivo de la caché de borde de CloudFront sin necesidad de que el usuario intervenga.

1. CloudFront utiliza la clave pública para validar la firma y confirmar que la URL no se ha manipulado. Si la firma no es válida, se rechaza la solicitud. 

   Si la firma es válida, CloudFront examina la instrucción de la política en la URL (o crea una si utiliza una política predefinida) para confirmar que la solicitud sigue siendo válida. Por ejemplo, si especifica una fecha y hora de inicio y fin de la URL, CloudFront confirma que el usuario intenta acceder al contenido durante el periodo que usted ha decidido permitir dicho acceso. 

   Si la solicitud cumple los requisitos de la instrucción de política, CloudFront realiza las operaciones estándar: determina si el archivo ya está en la caché de borde, reenvía la solicitud al origen en caso necesario y devuelve el archivo al usuario.

**nota**  
Si una URL sin firmar contiene parámetros de cadena de consulta, asegúrese de incluirlos en la parte de la dirección URL que firma. Si agrega una cadena de consulta a una URL firmada después de firmarla, la URL devuelve un estado HTTP 403.

## Decisión del tiempo de validez de las URL firmadas
<a name="private-content-overview-choosing-duration"></a>

Puede distribuir contenido privado mediante una URL firmada cuyo periodo de validez sea corto, incluso de unos pocos minutos. Las URL firmadas con un tiempo de validez tan corto son adecuadas para distribuir contenido sobre la marcha a un usuario con una finalidad específica, como la distribución de películas de alquiler o descargas de música bajo demanda para clientes. Si el periodo de validez de las URL firmadas es corto, es recomendable generarlas automáticamente con una aplicación que puede desarrollar. Cuando el usuario comienza a descargar un archivo o a reproducir un archivo multimedia, CloudFront compara la fecha y hora de vencimiento de la URL con el momento actual para determinar si la URL todavía es válida.

También puede distribuir contenido privado mediante una URL firmada con un periodo de validez más largo, de incluso años. Las URL válidas durante periodos largos resultan útiles para distribuir contenido privado a usuarios conocidos, como, por ejemplo, la distribución de un plan de negocio a inversores o la distribución de materiales de formación a los empleados. Puede desarrollar una aplicación para generar estas URL firmadas a largo plazo para usted.

## Cuándo comprueba CloudFront la fecha y hora de vencimiento de una URL firmada
<a name="private-content-check-expiration"></a>

CloudFront comprueba la fecha y hora de vencimiento de una URL firmada al realizarse la solicitud HTTP. Si un cliente comienza a descargar un archivo grande inmediatamente antes de la fecha de vencimiento, la descarga se realizará por completo incluso si se sobrepasa la hora de vencimiento durante la descarga. Si la conexión TCP se interrumpe y el cliente intenta reiniciar la descarga después de la fecha de vencimiento, la descarga fallará.

Si un cliente utiliza rangos GET para obtener un archivo en partes más pequeñas, cualquier solicitud GET que se produzca después de la fecha de vencimiento no se procesará. Para obtener más información acerca de Range GET, consulte [Cómo CloudFront procesa las solicitudes parciales de un objeto (rango GET)](RangeGETs.md).

## Código de ejemplo y herramientas de terceros
<a name="private-content-overview-sample-code"></a>

Para ver un código de ejemplo que crea la parte de las URL firmadas y a la que se le haya aplicado una función hash, consulte los siguientes temas:
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL con PHP](CreateURL_PHP.md)
+ [Crear una firma de URL mediante C\$1 y .NET Framework](CreateSignatureInCSharp.md)
+ [Crear una firma de URL con Java](CFPrivateDistJavaDevelopment.md)

# Creación de una URL firmada mediante una política predefinida
<a name="private-content-creating-signed-url-canned-policy"></a>

Para crear una URL firmada mediante una política predefinida, complete los pasos siguientes.<a name="private-content-creating-signed-url-canned-policy-procedure"></a>

**Para crear una URL firmada mediante una política predefinida**

1. Si utiliza. NET o Java para crear URL firmadas y no ha reformateado la clave privada del par de claves del formato .pem predeterminado a un formato compatible con .NET o con Java, hágalo ahora. Para obtener más información, consulte [Volver a formatear la clave privada (solo .NET y Java)](private-content-trusted-signers.md#private-content-reformatting-private-key).

1. Concatene los siguientes valores. Puede utilizar el formato de este ejemplo de URL firmada. 

   ```
   https://d111111abcdef8.cloudfront.net/image.jpg?color=red&size=medium&Expires=1767290400&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=K2JCJMDEHXQW5F
   ```

   Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva). Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación. Todos los valores tienen un tipo de `String`.  
**1. *URL base del archivo***  
La URL base es la URL de CloudFront que utilizaría para acceder al archivo si no utilizara las URL firmadas, incluidos los parámetros de la cadena de consulta propios, si los hay. En el ejemplo anterior, la URL base es `https://d111111abcdef8.cloudfront.net/image.jpg`. Para obtener más información acerca del formato de las URL para distribuciones, consulte [Personalización del formato de URL para archivos en CloudFront](LinkFormat.md).  
   + La siguiente URL de CloudFront es para un archivo de imagen en una distribución (utilizando el nombre de dominio de CloudFront). `image.jpg` está en un directorio `images`. La ruta hacia el archivo de la URL debe coincidir con la ruta hacia el archivo del servidor HTTP o del bucket de Amazon S3.

     `https://d111111abcdef8.cloudfront.net/images/image.jpg`
   + La siguiente URL de CloudFront incluye una cadena de consulta:

     `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large`
   + Las siguientes URL de CloudFront corresponden a archivos de imagen de una distribución. Ambas usan un nombre de dominio alternativo. La segunda incluye una cadena de consulta:

     `https://www.example.com/images/image.jpg`

     `https://www.example.com/images/image.jpg?color=red`
   + La siguiente URL de CloudFront corresponde a un archivo de imagen de una distribución que utiliza un nombre de dominio alternativo y el protocolo HTTPS:

     `https://www.example.com/images/image.jpg`  
** 2. `?`**  
`?` indica que los parámetros de consulta siguen la URL base. Incluya el parámetro `?` par si no especifica ningún otro parámetro de consulta.  
Puede especificar los siguientes parámetros de consulta en cualquier orden.  
**3. *Sus parámetros de cadena de consulta, de haberlos*`&`**  
(Opcional) Puede introducir sus propios parámetros de la cadena de consulta. Para ello, agregue un signo y (`&`) entre cada uno de ellos; por ejemplo, `color=red&size=medium`. Puede especificar los parámetros de consulta en cualquier orden dentro de la URL.  
Los parámetros de la cadena de consulta no podrán llamarse `Expires`, `Signature` ni `Key-Pair-Id`.  
** 4. `Expires=`*fecha y hora en formato de tiempo Unix (en segundos), en hora universal coordinada (UTC)***  
La fecha y la hora en las que desea que la URL deje de permitir el acceso al archivo.  
Especifique la fecha y la hora de vencimiento en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). Por ejemplo, 1 de enero de 2026 a las 10:00 UTC pasa a ser `1767290400` en formato de tiempo Unix, como se muestra en el ejemplo al principio de este tema.   
Para utilizar el tiempo de época, especifique un número entero de 64 bits para una fecha que no sea posterior a `9223372036854775807` (viernes, 11 de abril de 2262 a las 23:47:16.854 UTC).  
  
Para obtener información acerca de UTC, consulte [RFC 3339, fecha y hora en Internet: marcas temporales](https://tools.ietf.org/html/rfc3339).  
** 5. `&Signature=`*versión firmada y a la que se le ha aplicado una función hash de la instrucción de política***  
Una versión firmada, a la que se le ha aplicado una función hash y codificada en base64 de la instrucción de política JSON. Para obtener más información, consulte [Creación de una firma para una URL firmada que utiliza una política predefinida](#private-content-canned-policy-creating-signature).  
** 6. `&Key-Pair-Id=`*ID de clave pública para la clave pública de CloudFront cuya clave privada correspondiente va a utilizar para generar la firma***  
El ID de una clave pública de CloudFront, por ejemplo, `K2JCJMDEHXQW5F`. El ID de clave pública indica a CloudFront qué clave pública usar para validar la URL firmada. CloudFront compara la información de la firma con la información de la instrucción de política para comprobar que la URL no se ha manipulado.  
Esta clave pública debe pertenecer a un grupo de claves que tiene un signatario de confianza en la distribución. Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

## Creación de una firma para una URL firmada que utiliza una política predefinida
<a name="private-content-canned-policy-creating-signature"></a>

Para crear la firma para una URL firmada que utilice una política predefinida, realice los procedimientos indicados a continuación.

**Topics**
+ [Creación de una instrucción de política para una URL firmada que utiliza una política predefinida](#private-content-canned-policy-creating-policy-statement)
+ [Creación de una firma para una URL firmada que utiliza una política predefinida](#private-content-canned-policy-signing-policy-statement)

### Creación de una instrucción de política para una URL firmada que utiliza una política predefinida
<a name="private-content-canned-policy-creating-policy-statement"></a>

Al crear una URL firmada mediante una política predefinida, el parámetro `Signature` es una versión firmada y a la que se le ha aplicado una función hash de una instrucción de política. En el caso de URL firmadas que utilizan una política predefinida, la instrucción de política no se incluye en la URL, a diferencia de las URL firmadas que utilizan una política personalizada. Para crear la instrucción de política, siga el procedimiento que se indica a continuación.<a name="private-content-canned-policy-creating-policy-statement-procedure"></a>

**Para crear una instrucción de política para una URL firmada que use una política predefinida**

1. Cree la instrucción de política utilizando el siguiente formato JSON y codificación de caracteres UTF-8. Incluya toda la puntuación y otros valores literalmente, tal como se especifica. Para obtener más información acerca de los parámetros `Resource` y `DateLessThan`, consulte [Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política predefinida](#private-content-canned-policy-statement-values).

   ```
   {
       "Statement": [
           {
               "Resource": "base URL or stream name",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime": ending date and time in Unix time format and UTC
                   }
               }
           }
       ]
   }
   ```

1. Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la instrucción de la política. Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación.

#### Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política predefinida
<a name="private-content-canned-policy-statement-values"></a>

Al crear una instrucción de política para una política predefinida, debe especificar los siguientes valores.

**Recurso**  
Puede especificar solo un valor en `Resource`.
La URL base incluye las cadenas de consulta, de haberlas, pero excluye los parámetros de CloudFront `Expires`, `Signature` y `Key-Pair-Id`, por ejemplo:  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
Tenga en cuenta lo siguiente:  
+ **Protocol (Protocolo)**: el valor debe comenzar con `http://` o `https://`.
+ **Query string parameters (Parámetros de cadena de consulta)**: si no tiene parámetros de cadena de consulta, omita el signo de interrogación.
+ **Alternate domain names (Nombres de dominio alternativos)**: si especifica un nombre de dominio alternativo (CNAME) en la URL, debe especificarlo al hacer referencia al archivo en la página web o aplicación. No especifique la URL de Amazon S3 del objeto.

**DateLessThan**  
La fecha y hora de vencimiento de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). Por ejemplo, 1 de enero de 2026 a las 10:00 UTC pasa a ser 1767290400 en formato de tiempo Unix.  
Este valor debe coincidir con el valor del parámetro de cadena de consulta `Expires` de la URL firmada. No incluya el valor entre comillas.  
Para obtener más información, consulte [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una URL firmada](private-content-signed-urls.md#private-content-check-expiration).

#### Ejemplo de instrucción de política para una URL firmada que utiliza una política predefinida
<a name="private-content-canned-policy-creating-policy-statement-example"></a>

Cuando se utiliza la siguiente instrucción de política de ejemplo en una URL firmada, un usuario puede acceder al archivo `https://d111111abcdef8.cloudfront.net/horizon.jpg` hasta el 1 de enero de 2026 a las 10:00 UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/horizon.jpg?size=large&license=yes",
            "Condition": {
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

### Creación de una firma para una URL firmada que utiliza una política predefinida
<a name="private-content-canned-policy-signing-policy-statement"></a>

Para crear el valor del parámetro `Signature` en una URL firmada, aplique una función hash y firme la instrucción de política que ha creado en [Creación de una instrucción de política para una URL firmada que utiliza una política predefinida](#private-content-canned-policy-creating-policy-statement).

Para obtener más información y ejemplos de cómo resumir, aplicar una función hash y codificar la instrucción de política, consulte:
+ [Comandos de Linux y OpenSSL para codificación y cifrado base64](private-content-linux-openssl.md)
+ [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-canned-policy-creating-signature-download-procedure"></a>

**Opción 1: para crear una firma mediante una política predefinida**

1. Use la función hash SHA-1 y la clave privada RSA o ECDSA generada para codificar y firmar la instrucción de política creada en el procedimiento [Para crear una instrucción de política para una URL firmada que use una política predefinida](#private-content-canned-policy-creating-policy-statement-procedure). Utilice la versión de la instrucción de política que ya no incluye espacios vacíos.

   Para la clave privada requerida por la función hash, utilice una clave privada cuya clave pública esté en un grupo de claves de confianza activo para la distribución.
**nota**  
El método que utilice para resumir y aplicar una función hash la instrucción de política depende de su lenguaje de programación y plataforma. Para ver código de muestra, consulte [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md).

1. Elimine los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la cadena a la que se le ha aplicado una función hash y firmada.

1. Codifique la cadena con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html)

1. Añada el valor resultante a la URL firmada después de `&Signature=` y vuelva a [Para crear una URL firmada mediante una política predefinida](#private-content-creating-signed-url-canned-policy-procedure) para terminar de encadenar las partes de la URL firmada.

# Creación de una URL firmada mediante una política personalizada
<a name="private-content-creating-signed-url-custom-policy"></a>

Para crear una URL firmada mediante una política personalizada, realice el procedimiento que se indica a continuación.<a name="private-content-creating-signed-url-custom-policy-procedure"></a>

**Para crear una URL firmada mediante una política personalizada**

1. Si utiliza. NET o Java para crear URL firmadas y no ha reformateado la clave privada del par de claves del formato .pem predeterminado a un formato compatible con .NET o con Java, hágalo ahora. Para obtener más información, consulte [Volver a formatear la clave privada (solo .NET y Java)](private-content-trusted-signers.md#private-content-reformatting-private-key).

1. Concatene los siguientes valores. Puede utilizar el formato de este ejemplo de URL firmada.

   

   ```
   https://d111111abcdef8.cloudfront.net/image.jpg?color=red&size=medium&Policy=eyANCiAgICEXAMPLEW1lbnQiOiBbeyANCiAgICAgICJSZXNvdXJjZSI6Imh0dHA6Ly9kemJlc3FtN3VuMW0wLmNsb3VkZnJvbnQubmV0L2RlbW8ucGhwIiwgDQogICAgICAiQ29uZGl0aW9uIjp7IA0KICAgICAgICAgIklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIyMDcuMTcxLjE4MC4xMDEvMzIifSwNCiAgICAgICAgICJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI5Njg2MDE3Nn0sDQogICAgICAgICAiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyOTY4NjAyMjZ9DQogICAgICB9IA0KICAgfV0gDQp9DQo&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=K2JCJMDEHXQW5F
   ```

   Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva). Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación. Todos los valores tienen un tipo de `String`.  
**1. *URL base del archivo***  
La URL base es la URL de CloudFront que utilizaría para acceder al archivo si no utilizara las URL firmadas, incluidos los parámetros de la cadena de consulta propios, si los hay. En el ejemplo anterior, la URL base es `https://d111111abcdef8.cloudfront.net/image.jpg`. Para obtener más información acerca del formato de las URL para distribuciones, consulte [Personalización del formato de URL para archivos en CloudFront](LinkFormat.md).  
Los siguientes ejemplos muestran valores que especifica para distribuciones.  
   + La siguiente URL de CloudFront es para un archivo de imagen en una distribución (utilizando el nombre de dominio de CloudFront). `image.jpg` está en un directorio `images`. La ruta hacia el archivo de la URL debe coincidir con la ruta hacia el archivo del servidor HTTP o del bucket de Amazon S3.

     `https://d111111abcdef8.cloudfront.net/images/image.jpg`
   + La siguiente URL de CloudFront incluye una cadena de consulta:

     `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large`
   + Las siguientes URL de CloudFront corresponden a archivos de imagen de una distribución. Ambas utilizan un nombre de dominio alternativo; la segunda incluye una cadena de consulta:

     `https://www.example.com/images/image.jpg`

     `https://www.example.com/images/image.jpg?color=red`
   + La siguiente URL de CloudFront corresponde a un archivo de imagen de una distribución que utiliza un nombre de dominio alternativo y el protocolo HTTPS:

     `https://www.example.com/images/image.jpg`  
**2. `?`**  
`?` indica que los parámetros de la cadena de consulta siguen a la URL base. Incluya el parámetro `?` par si no especifica ningún otro parámetro de consulta.  
Puede especificar los siguientes parámetros de consulta en cualquier orden.  
**3. *Sus parámetros de cadena de consulta, de haberlos*`&`**  
(Opcional) Puede introducir sus propios parámetros de la cadena de consulta. Para ello, agregue un signo y (&) entre cada uno de ellos; por ejemplo, `color=red&size=medium`. Puede especificar los parámetros de consulta en cualquier orden dentro de la URL.  
Los parámetros de la cadena de consulta no podrán llamarse `Policy`, `Signature` ni `Key-Pair-Id`.
Si añade sus propios parámetros, incluya un `&` después de cada uno, incluso después del último.   
**4. `Policy=`*versión codificada con base64 de la instrucción de política***  
La instrucción de política en formato JSON después de haber eliminado los espacios vacíos y, a continuación, codificada con base64. Para obtener más información, consulte [Creación de una instrucción de política para una URL firmada que utiliza una política personalizada](#private-content-custom-policy-statement).  
La instrucción de política controla el acceso que una URL firmada concede a un usuario. Incluye la URL del archivo, una fecha y hora de vencimiento, una fecha y hora opcionales en que la URL se convierte en válida y una dirección IP opcional o un intervalo de direcciones IP a las que se permite acceder al archivo.  
**5. `&Signature=`*versión firmada y a la que se le ha aplicado una función hash de la instrucción de política***  
Una versión firmada, a la que se le ha aplicado una función hash y codificada en base64 de la instrucción de política JSON. Para obtener más información, consulte [Creación de una firma para una URL firmada que utiliza una política personalizada](#private-content-custom-policy-creating-signature).  
**6. `&Key-Pair-Id=`*ID de clave pública para la clave pública de CloudFront cuya clave privada correspondiente va a utilizar para generar la firma***  
El ID de una clave pública de CloudFront, por ejemplo, `K2JCJMDEHXQW5F`. El ID de clave pública indica a CloudFront qué clave pública usar para validar la URL firmada. CloudFront compara la información de la firma con la información de la instrucción de política para comprobar que la URL no se ha manipulado.  
Esta clave pública debe pertenecer a un grupo de claves que tiene un signatario de confianza en la distribución. Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

## Creación de una instrucción de política para una URL firmada que utiliza una política personalizada
<a name="private-content-custom-policy-statement"></a>

Complete los siguientes pasos para crear una instrucción de política para una URL firmada que utiliza una política personalizada.

Para consultar instrucciones de políticas de ejemplo que controlan el acceso a archivos de distintas maneras, consulte [Instrucciones de políticas de ejemplo para una URL firmada que utiliza una política personalizada](#private-content-custom-policy-statement-examples).<a name="private-content-custom-policy-creating-policy-procedure"></a>

**Para crear una instrucción de política para una URL firmada que use una política personalizada**

1. Cree la instrucción de política en el siguiente formato JSON. Sustituya los símbolos menor que (`<`) y mayor que (`>`) y las descripciones que contienen, por sus propios valores. Para obtener más información, consulte [Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política personalizada](#private-content-custom-policy-statement-values).

   ```
   {
       "Statement": [
           {
               "Resource": "<Optional but recommended: URL of the file>",
               "Condition": {
                   "DateLessThan": {
   	                "AWS:EpochTime": <Required: ending date and time in Unix time format and UTC>
                   },
                   "DateGreaterThan": {
   	                "AWS:EpochTime": <Optional: beginning date and time in Unix time format and UTC>
                   },
                   "IpAddress": {
   	                "AWS:SourceIp": "<Optional: IP address>"
                   }
               }
           }
       ]
   }
   ```

   Tenga en cuenta lo siguiente:
   + Puede incluir solo una instrucción en la política.
   + Utilice la codificación de caracteres UTF-8.
   + Incluya toda la puntuación y los nombres de parámetros exactamente como se especifica. No se aceptan abreviaturas de nombres de parámetros.
   + El orden de los parámetros de la sección `Condition` no importa.
   + Para obtener información acerca de valores para `Resource`, `DateLessThan`, `DateGreaterThan` y `IpAddress`, consulte [Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política personalizada](#private-content-custom-policy-statement-values).

1. Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la instrucción de la política. Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación.

1. Codifique la instrucción de política con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. Añada el valor resultante a la URL firmada después de `Policy=`.

1. Cree una firma para la URL firmada aplicando una función hash, firmando y codificando con base64 la instrucción de política. Para obtener más información, consulte [Creación de una firma para una URL firmada que utiliza una política personalizada](#private-content-custom-policy-creating-signature).

### Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política personalizada
<a name="private-content-custom-policy-statement-values"></a>

Al crear una instrucción de política para una política personalizada, debe especificar los siguientes valores.

**Resource**  
La URL, incluidas las cadenas de consulta, pero excluyendo los parámetros de CloudFront `Policy`, `Signature` y `Key-Pair-Id`. Por ejemplo:  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg\?size=large&license=yes`  
Puede especificar solo un valor de URL para `Resource`.  
Puede omitir el parámetro `Resource` en una política, pero hacerlo significa que cualquiera con la URL firmada puede acceder a *todos* los archivos en *cualquier* distribución asociada con el par de claves que utiliza para crear la URL firmada.
Tenga en cuenta lo siguiente:  
+ **Protocolo**: el valor debe comenzar con `http://`, `https://` o `*://`.
+ **Parámetros de cadena de consulta**: si la URL tiene parámetros de cadena de consulta, no utilice una barra oblicua inversa (`\`) para evitar el signo de interrogación (`?`) que comienza la cadena de consulta. Por ejemplo:

  `https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`
+ **Caracteres comodín**: puede utilizar caracteres comodín en la URL de la política. Se admiten los siguientes caracteres comodín:
  + asterisco (`*`), que busca coincidencias con cero o más caracteres
  + el signo de interrogación de cierre (`?`), que busca coincidencias exactamente con un carácter

  Cuando CloudFront hace coincidir la URL de la política con la URL de la solicitud HTTP, la URL de la política se divide en cuatro secciones (protocolo, dominio, ruta y cadena de consulta) de la siguiente manera:

  `[protocol]://[domain]/[path]\?[query string]`

  Al utilizar un carácter comodín en la URL de la política, la coincidencia de caracteres comodín solo se aplica dentro de los límites de la sección que contiene el comodín. Por ejemplo, considere esta URL en una política:

  `https://www.example.com/hello*world`

  En este ejemplo, el comodín asterisco (`*`) solo se aplica a la sección de rutas, por lo que coincide con las URL `https://www.example.com/helloworld` y `https://www.example.com/hello-world`, pero no con la URL `https://www.example.net/hello?world`.

  Las siguientes excepciones se aplican a los límites de las secciones para la coincidencia de caracteres comodín:
  + Un asterisco al final de la sección de rutas implica un asterisco en la sección de cadenas de consulta. Por ejemplo, `http://example.com/hello*` equivale a `http://example.com/hello*\?*`.
  + Un asterisco al final de la sección de dominio implica un asterisco en la secciones de ruta y cadena de consulta. Por ejemplo, `http://example.com*` equivale a `http://example.com*/*\?*`.
  + Una URL en la política puede omitir la sección de protocolo y empezar con un asterisco en la sección de dominio. En ese caso, la sección de protocolo se establece implícitamente en un asterisco. Por ejemplo, la URL `*example.com` en una política es equivalente a `*://*example.com/`.
  + Un asterisco por sí solo (`"Resource": "*"`) coincide con cualquier URL.

  Por ejemplo, el valor: `https://d111111abcdef8.cloudfront.net/*game_download.zip*` en una política coincide con todas las URL siguientes:
  + `https://d111111abcdef8.cloudfront.net/game_download.zip`
  + `https://d111111abcdef8.cloudfront.net/example_game_download.zip?license=yes`
  + `https://d111111abcdef8.cloudfront.net/test_game_download.zip?license=temp`
+ **Nombres de dominio alternativos**: si especifica un nombre de dominio alternativo (CNAME) en la URL de la política, la solicitud HTTP debe usar el nombre de dominio alternativo en la página web o aplicación. No especifique la URL de Amazon S3 para el archivo en una política.

**DateLessThan**  
La fecha y hora de vencimiento de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). En la política, no incluya el valor entre comillas. Para obtener información acerca de UTC, consulte [Fecha y hora en Internet: marcas temporales](https://tools.ietf.org/html/rfc3339).  
Por ejemplo, el 31 de enero de 2023 a las 10:00 UTC pasa a ser 1675159200 en formato de tiempo Unix.  
Este es el único parámetro requerido en la sección `Condition`. CloudFront requiere este valor para impedir que los usuarios tengan acceso permanente al contenido privado.  
Para obtener más información, consulte [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una URL firmada](private-content-signed-urls.md#private-content-check-expiration)

**DateGreaterThan (opcional)**  
Una fecha y hora de inicio opcionales de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). Los usuarios no pueden acceder al archivo en la fecha y hora especificadas ni antes. No incluya el valor entre comillas. 

**IpAddress (opcional)**  
La dirección IP del cliente que hace la solicitud HTTP. Tenga en cuenta lo siguiente:  
+ Para permitir que cualquier dirección IP obtenga acceso al archivo, omita el parámetro `IpAddress`.
+ Puede especificar una dirección IP o a un rango de direcciones IP. No puede usar la política para permitir el acceso si la dirección IP del cliente está en uno de dos rangos separados.
+ Para permitir el acceso desde una única dirección IP, especifique:

  `"`*Dirección IP IPv*`/32"`
+ Debe especificar rangos de direcciones IP en formato estándar IPv4 CIDR (por ejemplo, `192.0.2.0/24`). Para obtener más información, consulte [Enrutamiento entre dominios sin clases (CIDR): Asignación de dirección de Internet y plan de agregación](https://tools.ietf.org/html/rfc4632).
**importante**  
Las direcciones IP en formato IPv6, como 2001:0db8:85a3::8a2e:0370:7334, no son compatibles. 

  Si está utilizando una política personalizada que incluya `IpAddress`, no habilite IPv6 para la distribución. Si desea restringir el acceso a algún contenido por dirección IP y admite solicitudes IPv6 de otro contenido, puede crear dos distribuciones. Para obtener más información, consulte [Habilitación de IPv6 (solicitudes de espectadores)](DownloadDistValuesGeneral.md#DownloadDistValuesEnableIPv6) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).

## Instrucciones de políticas de ejemplo para una URL firmada que utiliza una política personalizada
<a name="private-content-custom-policy-statement-examples"></a>

En los siguientes ejemplos de instrucciones de políticas, se muestra cómo controlar el acceso a un archivo específico, a todos los archivos de un directorio o a todos los archivos asociados a un ID de par de claves. Los ejemplos también muestran cómo controlar el acceso desde una dirección IP individual o a un rango de direcciones IP, y cómo impedir que los usuarios utilicen la URL firmada después de una fecha y hora específicas.

Si copia y pega cualquiera de estos ejemplos, elimine los espacios vacíos (incluidos los tabuladores y los caracteres de línea nueva), sustituya los valores por sus propios valores e incluya un carácter de línea nueva después de la llave de cierre (`}`).

Para obtener más información, consulte [Valores que se especifican en la instrucción de política de una URL firmada que utiliza una política personalizada](#private-content-custom-policy-statement-values).

**Topics**
+ [Ejemplo de instrucción de política: acceso a un archivo desde un intervalo de direcciones IP](#private-content-custom-policy-statement-example-one-object)
+ [Ejemplo de instrucción de política: acceso a todos los archivos de un directorio desde un intervalo de direcciones IP](#private-content-custom-policy-statement-example-all-objects)
+ [Ejemplo de instrucción de política: acceso a todos los archivos asociados con un ID de par de claves desde una dirección IP](#private-content-custom-policy-statement-example-one-ip)

### Ejemplo de instrucción de política: acceso a un archivo desde un intervalo de direcciones IP
<a name="private-content-custom-policy-statement-example-one-object"></a>

En el siguiente ejemplo de política personalizada de una URL firmada se especifica que un usuario puede acceder al archivo `https://d111111abcdef8.cloudfront.net/game_download.zip` desde las direcciones IP del intervalo `192.0.2.0/24` hasta el 31 de enero de 2023 a las 10:00 UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/game_download.zip",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675159200
                }
            }
        }
    ]
}
```

### Ejemplo de instrucción de política: acceso a todos los archivos de un directorio desde un intervalo de direcciones IP
<a name="private-content-custom-policy-statement-example-all-objects"></a>

La siguiente política personalizada de ejemplo le permite crear URL firmadas para cualquier archivo del directorio `training`, tal y como indica el carácter comodín asterisco (`*`) del parámetro `Resource`. Los usuarios pueden acceder al archivo desde una dirección IP incluida en el rango `192.0.2.0/24` hasta el 31 de enero de 2023 a las 10:00 UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/training/*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675159200
                }
            }
        }
    ]
}
```

Cada URL firmada con la que utilice esta política tiene una URL que identifica a un archivo específico, por ejemplo:

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

### Ejemplo de instrucción de política: acceso a todos los archivos asociados con un ID de par de claves desde una dirección IP
<a name="private-content-custom-policy-statement-example-one-ip"></a>

La siguiente política personalizada de ejemplo le permite crear URL firmadas para cualquier archivo asociado a cualquier distribución, tal y como indica el carácter comodín asterisco (`*`) del parámetro `Resource`. La URL firmada debe usar el protocolo `https://`, no `http://`. El usuario debe utilizar la dirección IP `192.0.2.10/32`. (El valor `192.0.2.10/32` en notación CIDR se refiere a la dirección IP individual `192.0.2.10`). Los archivos solo van a estar disponibles desde el 31 de enero de 2023 a las 10:00 UTC hasta el 2 de febrero de 2023 a las 10:00 UTC:

```
{
    "Statement": [
       {
            "Resource": "https://*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.10/32"
                },
                "DateGreaterThan": {
                    "AWS:EpochTime": 1675159200
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675332000
                }
            }
        }
    ]
}
```

Cada URL firmada con la que utilice esta política tiene una URL que identifica un archivo específico de una distribución de CloudFront específica; por ejemplo:

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

La URL firmada también incluye un ID de par de claves que se debe asociar con un grupo de claves de confianza en la distribución (d111111abcdef8.cloudfront.net) que se especifica en la URL.

## Creación de una firma para una URL firmada que utiliza una política personalizada
<a name="private-content-custom-policy-creating-signature"></a>

La firma de una URL firmada que utiliza una política personalizada es una versión de la instrucción de política a la que se le ha aplicado una función hash, firmada y codificada con base64. Para crear una firma para una política personalizada, complete los pasos siguientes.

Para obtener más información y ejemplos de cómo resumir, aplicar una función hash y codificar la instrucción de política, consulte:
+ [Comandos de Linux y OpenSSL para codificación y cifrado base64](private-content-linux-openssl.md)
+ [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-custom-policy-creating-signature-download-procedure"></a>

**Opción 1: para crear una firma mediante una política personalizada**

1. Use la función hash SHA-1 y la clave privada RSA o ECDSA generada para codificar y firmar la instrucción de política JSON creada en el procedimiento [Para crear una instrucción de política para una URL firmada que use una política personalizada](#private-content-custom-policy-creating-policy-procedure). Utilice la versión de la instrucción de política que ya no incluye espacios vacíos pero que aún no se ha codificado con base64.

   Para la clave privada requerida por la función hash, utilice una clave privada cuya clave pública esté en un grupo de claves de confianza activo para la distribución.
**nota**  
El método que utilice para resumir y aplicar una función hash la instrucción de política depende de su lenguaje de programación y plataforma. Para ver código de muestra, consulte [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md).

1. Elimine los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la cadena a la que se le ha aplicado una función hash y firmada.

1. Codifique la cadena con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. Añada el valor resultante a la URL firmada después de `&Signature=` y vuelva a [Para crear una URL firmada mediante una política personalizada](#private-content-creating-signed-url-custom-policy-procedure) para terminar de encadenar las partes de la URL firmada.

# Uso de cookies firmadas
<a name="private-content-signed-cookies"></a>

Las cookies firmadas de CloudFront le permiten controlar quién puede acceder al contenido cuando no desea cambiar las URL actuales o cuando desea proporcionar acceso a varios archivos restringidos, por ejemplo, todos los archivos del área de suscriptores de un sitio web. En este tema se explica qué tomar en cuenta al utilizar cookies firmadas y describe cómo configurarlas mediante políticas predefinidas o personalizadas.

**Topics**
+ [Decisión de utilizar políticas predefinidas o personalizadas para cookies firmadas](#private-content-choosing-canned-custom-cookies)
+ [Cómo funcionan las cookies firmadas](#private-content-how-signed-cookies-work)
+ [Prevención del uso indebido de cookies firmadas](#private-content-signed-cookie-misuse)
+ [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una cookie firmada](#private-content-check-expiration-cookie)
+ [Código de muestra y herramientas de terceros](#private-content-overview-sample-code-cookies)
+ [Establecimiento de cookies firmadas mediante una política predefinida](private-content-setting-signed-cookie-canned-policy.md)
+ [Establecimiento de cookies firmadas mediante una política personalizada](private-content-setting-signed-cookie-custom-policy.md)
+ [Create signed cookies using PHP](signed-cookies-PHP.md)

## Decisión de utilizar políticas predefinidas o personalizadas para cookies firmadas
<a name="private-content-choosing-canned-custom-cookies"></a>

Al crear una cookie firmada, se escribe una instrucción de política en formato JSON que especifica las restricciones en la cookie firmada, por ejemplo, el tiempo de validez de la cookie. Puede utilizar políticas predefinidas o personalizadas. En la siguiente tabla se comparan las políticas predefinidas y las personalizadas:


****  

| Descripción | Política predefinida | Política personalizada | 
| --- | --- | --- | 
| Puede reutilizar la instrucción de la política con varios archivos. Para reutilizar la instrucción de política, debe utilizar caracteres comodín en el objeto `Resource`. Para obtener más información, consulte ). [Valores que se especifican en la instrucción de política de una política personalizada para cookies firmadas](private-content-setting-signed-cookie-custom-policy.md#private-content-custom-policy-statement-cookies-values).)  | No | Sí | 
| Puede especificar la fecha y la hora a la que los usuarios pueden empezar a obtener acceso a su contenido. | No | Sí (opcional) | 
| Puede especificar la fecha y la hora a la que los usuarios dejan de obtener acceso a su contenido. | Sí | Sí | 
| Puede especificar la dirección IP o a un rango de direcciones IP de los usuarios que pueden obtener acceso a su contenido. | No | Sí (opcional) | 

Para obtener información acerca de cómo crear cookies firmadas mediante una política predefinida, consulte [Establecimiento de cookies firmadas mediante una política predefinida](private-content-setting-signed-cookie-canned-policy.md).

Para obtener información acerca de cómo crear cookies firmadas mediante una política personalizada, consulte [Establecimiento de cookies firmadas mediante una política personalizada](private-content-setting-signed-cookie-custom-policy.md).

## Cómo funcionan las cookies firmadas
<a name="private-content-how-signed-cookies-work"></a>

A continuación, se muestra información general acerca de cómo configurar CloudFront para cookies firmadas y cómo responde CloudFront cuando un usuario envía una solicitud que contiene una cookie firmada. 

1. En la distribución de CloudFront, especifique uno o más grupos de claves de confianza, que contienen las claves públicas que CloudFront puede utilizar para comprobar la firma de URL. Se utilizan las claves privadas correspondientes para firmar las URL.

   Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

1. Desarrolle una aplicación para determinar si un usuario debe obtener acceso a su contenido y, en caso de que sí, que envíe 3 encabezados `Set-Cookie` al espectador. (Cada encabezado `Set-Cookie` puede contener solo un par de nombre-valor y una cookie de CloudFront firmada requiere tres pares de nombre-valor). Debe enviar los encabezados `Set-Cookie` al espectador antes de que el usuario solicite su contenido privado. Si configura un periodo de vencimiento corto en la cookie, le recomendamos enviar tres encabezados `Set-Cookie` más en respuesta a solicitudes posteriores, de modo que el usuario continúe teniendo acceso.

   Normalmente, la distribución de CloudFront tendrá al menos dos comportamientos de la caché: uno que no requiere autenticación y otro que sí. La página de error de la parte segura del sitio incluye un redirector o un enlace a una página de inicio de sesión.

   Si configura la distribución para que el almacenamiento de archivos en la caché dependa de las cookies, CloudFront no almacenará archivos independientes en la caché en función de los atributos de las cookies firmadas.

1. Un usuario inicia sesión en su sitio web y paga por el contenido o cumple algún otro requisito para el acceso.

1. Su aplicación devuelve los encabezados `Set-Cookie` en la respuesta, y el espectador almacena los pares nombre-valor.

1. El usuario solicita un archivo.

   El navegador del usuario o cualquier otro espectador obtiene los pares nombre-valor del paso 4 y los añade a la solicitud en un encabezado `Cookie`. Esta es la cookie firmada.

1. CloudFront utiliza la clave pública para validar la firma en la cookie firmada y confirmar que dicha cookie no se ha manipulado. Si la firma no es válida, se rechaza la solicitud.

   Si la firma de la cookie es válida, CloudFront examina la instrucción de la política en la cookie (o crea una si utiliza una política predefinida) para confirmar que la solicitud sigue siendo válida. Por ejemplo, si ha especificado una fecha y hora de inicio y fin de la cookie, CloudFront confirma que el usuario intenta acceder al contenido durante el periodo en el que ha decidido permitir dicho acceso.

   Si la solicitud cumple los requisitos de la instrucción de la política, CloudFront enviará el contenido del mismo modo que envía el contenido no restringido: determina si el archivo ya está en la caché de borde, reenvía la solicitud al origen en caso necesario y devuelve el archivo al usuario.

## Prevención del uso indebido de cookies firmadas
<a name="private-content-signed-cookie-misuse"></a>

Si especifica el parámetro `Domain` en un encabezado `Set-Cookie`, especifique el valor de la forma más precisa posible para reducir el acceso potencial por parte de alguien con el mismo nombre de dominio raíz. Por ejemplo, app.example.com es mejor que example.com, especialmente si no controla example.com. Esto ayuda a impedir que alguien obtenga acceso a su contenido desde www.example.com.

Para evitar este tipo de ataques, haga lo siguiente:
+ Excluya los atributos de cookies `Expires` y `Max-Age` para que el encabezado `Set-Cookie` cree una cookie de sesión. Las cookies de sesión se eliminan automáticamente cuando el usuario cierra el navegador, lo que reduce la posibilidad de alguien obtenga acceso no autorizado a su contenido.
+ Incluya el atributo `Secure` para que la cookie se cifre cuando un espectador la incluya en una solicitud.
+ De ser posible, utilice una política personalizada e incluya la dirección IP del espectador.
+ En el atributo `CloudFront-Expires`, especifique el menor tiempo de vencimiento posible pero razonable en función de por cuánto tiempo desea que los usuarios puedan obtener acceso a su contenido.

## Cuándo comprueba CloudFront la fecha y hora de vencimiento de una cookie firmada
<a name="private-content-check-expiration-cookie"></a>

Para determinar si una cookie firmada sigue siendo válida, CloudFront comprueba la fecha y hora de vencimiento de la cookie en el momento de la solicitud HTTP. Si un cliente comienza a descargar un archivo grande inmediatamente antes de la fecha de vencimiento, la descarga se realizará por completo incluso si se sobrepasa la hora de vencimiento durante la descarga. Si la conexión TCP se interrumpe y el cliente intenta reiniciar la descarga después de la fecha de vencimiento, la descarga fallará.

Si un cliente utiliza rangos GET para obtener un archivo en partes más pequeñas, cualquier solicitud GET que se produzca después de la fecha de vencimiento no se procesará. Para obtener más información acerca de Range GET, consulte [Cómo CloudFront procesa las solicitudes parciales de un objeto (rango GET)](RangeGETs.md).

## Código de muestra y herramientas de terceros
<a name="private-content-overview-sample-code-cookies"></a>

El código de muestra para contenido privado solo muestra cómo crear firmas para URL firmadas. Sin embargo, el proceso de creación de una firma para una cookie firmada es muy similar, así que gran parte del código de muestra es aplicable. Para obtener más información, consulte los temas siguientes: 
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL con PHP](CreateURL_PHP.md)
+ [Crear una firma de URL mediante C\$1 y .NET Framework](CreateSignatureInCSharp.md)
+ [Crear una firma de URL con Java](CFPrivateDistJavaDevelopment.md)

# Establecimiento de cookies firmadas mediante una política predefinida
<a name="private-content-setting-signed-cookie-canned-policy"></a>

Para establecer una cookie firmada utilizando una política predefinida, complete los pasos siguientes. Para crear la firma, consulte [Creación de una firma para una cookie firmada que utiliza una política predefinida](#private-content-canned-policy-signature-cookies).<a name="private-content-setting-signed-cookie-canned-policy-procedure"></a>

**Para establecer cookies firmadas mediante una política predefinida**

1. Si utiliza. NET o Java para crear cookies firmadas y no ha reformateado la clave privada del par de claves del formato .pem predeterminado a un formato compatible con .NET o con Java, hágalo ahora. Para obtener más información, consulte [Volver a formatear la clave privada (solo .NET y Java)](private-content-trusted-signers.md#private-content-reformatting-private-key).

1. Programe su aplicación para enviar tres encabezados `Set-Cookie` a los espectadores aprobados. Necesita tres encabezados `Set-Cookie` porque cada encabezado `Set-Cookie` puede contener solo un par de nombre-valor y una cookie firmada de CloudFront requiere tres pares de nombre-valor. Los pares de nombre-valor son: `CloudFront-Expires`, `CloudFront-Signature` y `CloudFront-Key-Pair-Id`. Los valores deben estar presentes en el lector antes de que un usuario realice la primera solicitud de un archivo cuyo acceso desea controlar. 
**nota**  
En general, recomendamos que excluya los atributos `Expires` y `Max-Age`. Al excluir los atributos, el navegador elimina la cookie cuando el usuario lo cierra, lo que reduce la posibilidad de alguien obtenga acceso no autorizado a su contenido. Para obtener más información, consulte [Prevención del uso indebido de cookies firmadas](private-content-signed-cookies.md#private-content-signed-cookie-misuse).

   **Los nombres de los atributos de las cookies distinguen entre mayúsculas y minúsculas**. 

   Los saltos de línea se incluyen únicamente para que los atributos sean más legibles.

   ```
   Set-Cookie: 
   CloudFront-Expires=date and time in Unix time format (in seconds) and Coordinated Universal Time (UTC); 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Signature=hashed and signed version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Key-Pair-Id=public key ID for the CloudFront public key whose corresponding private key you're using to generate the signature; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   ```  
**(Opcional) `Domain`**  
Nombre de dominio del archivo solicitado. Si no especifica un atributo `Domain`, el valor predeterminado será el nombre de dominio de la URL; esto es aplicable solo al nombre de dominio especificado, no a subdominios. Si especifica un atributo `Domain`, también será aplicable a subdominios. Un punto al inicio del nombre de dominio (por ejemplo, `Domain=.example.com`) es opcional. Además, si no especifica un atributo `Domain`, el nombre de dominio de la URL y el valor del atributo `Domain` deberán coincidir.  
Puede especificar el nombre de dominio que CloudFront ha asignado a la distribución, por ejemplo, d111111abcdef8.cloudfront.net, pero no puede especificar \$1.cloudfront.net para el nombre de dominio.  
Si desea utilizar un nombre de dominio alternativo como example.com en las URL, debe añadir dicho nombre de dominio a su distribución independientemente de que especifique el atributo `Domain`. Para obtener más información, consulte [Nombres de dominio alternativos (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).  
**(Opcional) `Path`**  
Ruta del archivo solicitado. Si no especifica un atributo `Path`, el valor predeterminado será la ruta de la URL.  
**`Secure`**  
Requiere que el espectador cifre cookies antes de enviar una solicitud. Recomendamos que envíe el encabezado `Set-Cookie` a través de una conexión HTTPS para asegurarse de que los atributos de la cookie estén protegidos contra ataques man-in-the-middle.  
**`HttpOnly`**  
Define la forma en que el navegador (si es compatible) interactúa con el valor de la cookie. Con `HttpOnly`, JavaScript no puede acceder a los valores de las cookies. Esta precaución puede ayudar a mitigar los ataques de scripting entre sitios (XSS). Para obtener más información, consulte [Using HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies).  
**`CloudFront-Expires`**  
Especifique la fecha y la hora de vencimiento en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). Por ejemplo, 1 de enero de 2026 a las 10:00 UTC pasa a ser 1767290400 en formato de tiempo Unix.   
Para utilizar el tiempo de época, especifique un número entero de 64 bits para una fecha que no sea posterior a `9223372036854775807` (viernes, 11 de abril de 2262 a las 23:47:16.854 UTC).  
Para obtener información acerca de UTC, consulte *RFC 3339, fecha y hora en Internet: marcas temporales*, [https://tools.ietf.org/html/rfc3339](https://tools.ietf.org/html/rfc3339).  
**`CloudFront-Signature`**  
Una versión de una instrucción de política JSON firmada, a la que se le ha aplicado una función hash y codificada en base64. Para obtener más información, consulte [Creación de una firma para una cookie firmada que utiliza una política predefinida](#private-content-canned-policy-signature-cookies).  
**`CloudFront-Key-Pair-Id`**  
El ID de una clave pública de CloudFront, por ejemplo, `K2JCJMDEHXQW5F`. El ID de clave pública indica a CloudFront qué clave pública usar para validar la URL firmada. CloudFront compara la información de la firma con la información de la instrucción de política para comprobar que la URL no se ha manipulado.  
Esta clave pública debe pertenecer a un grupo de claves que tiene un signatario de confianza en la distribución. Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

En el ejemplo siguiente, se muestran los encabezados `Set-Cookie` de una cookie firmada cuando se usa el nombre de dominio asociado a la distribución en las URL de los archivos:

```
Set-Cookie: CloudFront-Expires=1426500000; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=yXrSIgyQoeE4FBI4eMKF6ho~CA8_; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
```

En el ejemplo siguiente, se muestran los encabezados `Set-Cookie` de una cookie firmada cuando se usa el nombre de dominio alternativo example.org en las URL de los archivos:

```
Set-Cookie: CloudFront-Expires=1426500000; Domain=example.org; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=yXrSIgyQoeE4FBI4eMKF6ho~CA8_; Domain=example.org; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/images/*; Secure; HttpOnly
```

Si desea utilizar un nombre de dominio alternativo como example.com en las URL, debe añadir dicho nombre de dominio a su distribución independientemente de que especifique el atributo `Domain`. Para obtener más información, consulte [Nombres de dominio alternativos (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).

## Creación de una firma para una cookie firmada que utiliza una política predefinida
<a name="private-content-canned-policy-signature-cookies"></a>

Para crear la firma para una cookie firmada que utilice una política predefinida, realice los procedimientos indicados a continuación.

**Topics**
+ [Creación de una instrucción de política para una cookie firmada que use una política predefinida](#private-content-canned-policy-statement-cookies)
+ [Firma de la instrucción de política para crear una firma para una cookie firmada que utiliza una política predefinida](#private-content-canned-policy-cookies-signing-policy-statement)

### Creación de una instrucción de política para una cookie firmada que use una política predefinida
<a name="private-content-canned-policy-statement-cookies"></a>

Al establecer una cookie firmada que use una política predefinida, el atributo `CloudFront-Signature` es una versión de una instrucción de política firmada y a la que se le ha aplicado una función hash. En el caso de cookies firmadas que utilizan una política predefinida, la instrucción de política no se incluye en el encabezado `Set-Cookie`, a diferencia de las cookies firmadas que utilizan una política personalizada. Para crear la instrucción de política, complete los pasos siguientes.<a name="private-content-canned-policy-statement-cookies-procedure"></a>

**Para crear una instrucción de política para una cookie firmada que use una política predefinida**

1. Cree la instrucción de política utilizando el siguiente formato JSON y codificación de caracteres UTF-8. Incluya toda la puntuación y otros valores literalmente, tal como se especifica. Para obtener más información acerca de los parámetros `Resource` y `DateLessThan`, consulte [Valores que se especifican en la instrucción de política de una política predefinida para cookies firmadas](#private-content-canned-policy-statement-cookies-values).

   ```
   {
       "Statement": [
           {
               "Resource": "base URL or stream name",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime": ending date and time in Unix time format and UTC
                   }
               }
           }
       ]
   }
   ```

1. Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la instrucción de la política. Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación.

#### Valores que se especifican en la instrucción de política de una política predefinida para cookies firmadas
<a name="private-content-canned-policy-statement-cookies-values"></a>

Al crear una instrucción de una política predefinida, debe especificar los siguientes valores:

**Recurso**  
La URL base, incluidas las cadenas de consulta, de haberlas; por ejemplo:  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
Puede especificar solo un valor en `Resource`.  
Tenga en cuenta lo siguiente:  
+ **Protocol (Protocolo)**: el valor debe comenzar con `http://` o `https://`.
+ **Query string parameters (Parámetros de cadena de consulta)**: si no tiene parámetros de cadena de consulta, omita el signo de interrogación.
+ **Alternate domain names (Nombres de dominio alternativos)**: si especifica un nombre de dominio alternativo (CNAME) en la URL, debe especificarlo al hacer referencia al archivo en la página web o aplicación. No especifique la URL de Amazon S3 para el archivo.

**DateLessThan**  
La fecha y hora de vencimiento de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). No incluya el valor entre comillas.  
Por ejemplo, 16 de marzo de 2015 a las 10:00 h UTC pasa a ser 1426500000 en formato de tiempo Unix.  
Este valor debe coincidir con el valor del atributo `CloudFront-Expires` en el encabezado `Set-Cookie`. No incluya el valor entre comillas.  
Para obtener más información, consulte [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una cookie firmada](private-content-signed-cookies.md#private-content-check-expiration-cookie).

#### Ejemplo de instrucción de política para una política predefinida
<a name="private-content-canned-policy-cookies-sample-policy-statement"></a>

Si se utiliza el siguiente ejemplo de instrucción de política en una cookie firmada, los usuarios podrán obtener acceso al archivo `https://d111111abcdef8.cloudfront.net/horizon.jpg` hasta el 16 de marzo de 2015 a las 10:00 h UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/horizon.jpg?size=large&license=yes",
            "Condition": {
                "DateLessThan": {
                    "AWS:EpochTime": 1426500000
                }
            }
        }
    ]
}
```

### Firma de la instrucción de política para crear una firma para una cookie firmada que utiliza una política predefinida
<a name="private-content-canned-policy-cookies-signing-policy-statement"></a>

Para crear el valor del atributo `CloudFront-Signature` en un encabezado `Set-Cookie`, aplique una función hash y firme la instrucción de política creada en [Para crear una instrucción de política para una cookie firmada que use una política predefinida](#private-content-canned-policy-statement-cookies-procedure). 

Para obtener más información y ejemplos de cómo aplicar una función hash, firmar y codificar la instrucción de política, consulte los siguientes temas:
+ [Comandos de Linux y OpenSSL para codificación y cifrado base64](private-content-linux-openssl.md)
+ [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-canned-policy-cookie-creating-signature-procedure"></a>

**Para crear una firma para una cookie firmada que use una política predefinida**

1. Use la función hash SHA-1 y RSA para resumir y firmar la instrucción de política creada en el procedimiento [Para crear una instrucción de política para una cookie firmada que use una política predefinida](#private-content-canned-policy-statement-cookies-procedure). Utilice la versión de la instrucción de política que ya no incluye espacios vacíos.

   Para la clave privada requerida por la función hash, utilice una clave privada cuya clave pública esté en un grupo de claves de confianza activo para la distribución.
**nota**  
El método que utilice para resumir y aplicar una función hash la instrucción de política depende de su lenguaje de programación y plataforma. Para ver código de muestra, consulte [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md).

1. Elimine los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la cadena a la que se le ha aplicado una función hash y firmada.

1. Codifique la cadena con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-canned-policy.html)

1. Incluya el valor resultante en el encabezado `Set-Cookie` para el par nombre-valor `CloudFront-Signature`. A continuación, vuelva a [Para establecer cookies firmadas mediante una política predefinida](#private-content-setting-signed-cookie-canned-policy-procedure) y añada el encabezado `Set-Cookie` en `CloudFront-Key-Pair-Id`.

# Establecimiento de cookies firmadas mediante una política personalizada
<a name="private-content-setting-signed-cookie-custom-policy"></a>

Para establecer una cookie firmada que utiliza una política personalizada, complete los siguientes pasos.<a name="private-content-setting-signed-cookie-custom-policy-procedure"></a>

**Para establecer cookies firmadas mediante una política personalizada**

1. Si utiliza. NET o Java para crear URL firmadas y no ha reformateado la clave privada del par de claves del formato .pem predeterminado a un formato compatible con .NET o con Java, hágalo ahora. Para obtener más información, consulte [Volver a formatear la clave privada (solo .NET y Java)](private-content-trusted-signers.md#private-content-reformatting-private-key).

1. Programe su aplicación para enviar tres encabezados `Set-Cookie` a los espectadores aprobados. Necesita tres encabezados `Set-Cookie` porque cada encabezado `Set-Cookie` puede contener solo un par de nombre-valor y una cookie firmada de CloudFront requiere tres pares de nombre-valor. Los pares de nombre-valor son: `CloudFront-Policy`, `CloudFront-Signature` y `CloudFront-Key-Pair-Id`. Los valores deben estar presentes en el lector antes de que un usuario realice la primera solicitud de un archivo cuyo acceso desea controlar. 
**nota**  
En general, recomendamos que excluya los atributos `Expires` y `Max-Age`. Al excluirlos, el navegador elimina la cookie cuando el usuario lo cierra, lo que reduce la posibilidad de alguien obtenga acceso no autorizado a su contenido. Para obtener más información, consulte [Prevención del uso indebido de cookies firmadas](private-content-signed-cookies.md#private-content-signed-cookie-misuse).

   **Los nombres de los atributos de las cookies distinguen entre mayúsculas y minúsculas**. 

   Los saltos de línea se incluyen únicamente para que los atributos sean más legibles.

   ```
   Set-Cookie: 
   CloudFront-Policy=base64 encoded version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   
   Set-Cookie: 
   CloudFront-Signature=hashed and signed version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Key-Pair-Id=public key ID for the CloudFront public key whose corresponding private key you're using to generate the signature; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   ```  
**(Opcional) `Domain`**  
Nombre de dominio del archivo solicitado. Si no especifica un atributo `Domain`, el valor predeterminado será el nombre de dominio de la URL; esto es aplicable solo al nombre de dominio especificado, no a subdominios. Si especifica un atributo `Domain`, también será aplicable a subdominios. Un punto al inicio del nombre de dominio (por ejemplo, `Domain=.example.com`) es opcional. Además, si no especifica un atributo `Domain`, el nombre de dominio de la URL y el valor del atributo `Domain` deberán coincidir.  
Puede especificar el nombre de dominio que CloudFront ha asignado a la distribución, por ejemplo, d111111abcdef8.cloudfront.net, pero no puede especificar \$1.cloudfront.net para el nombre de dominio.  
Si desea utilizar un nombre de dominio alternativo como example.com en las URL, debe añadir dicho nombre de dominio a su distribución independientemente de que especifique el atributo `Domain`. Para obtener más información, consulte [Nombres de dominio alternativos (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).  
**(Opcional) `Path`**  
Ruta del archivo solicitado. Si no especifica un atributo `Path`, el valor predeterminado será la ruta de la URL.  
**`Secure`**  
Requiere que el espectador cifre cookies antes de enviar una solicitud. Recomendamos que envíe el encabezado `Set-Cookie` a través de una conexión HTTPS para asegurarse de que los atributos de la cookie estén protegidos contra ataques man-in-the-middle.  
**`HttpOnly`**  
Requiere que el espectador envíe la cookie únicamente en solicitudes de HTTP o HTTPS.  
**`CloudFront-Policy`**  
La instrucción de política en formato JSON después de haber eliminado los espacios vacíos y, a continuación, codificada con base64. Para obtener más información, consulte [Creación de una firma para una cookie firmada que utiliza una política personalizada](#private-content-custom-policy-signature-cookies).  
La instrucción de política controla el acceso que una cookie firmada concede a un usuario. Incluye los archivos a los que el usuario puede acceder, una fecha y hora de vencimiento, una fecha y hora opcionales a las que la URL se convierte en válida y una dirección IP opcional o un intervalo de direcciones IP a las que se permite acceder al archivo.  
**`CloudFront-Signature`**  
Una versión firmada, a la que se le ha aplicado una función hash y codificada en base64 de la instrucción de política JSON. Para obtener más información, consulte [Creación de una firma para una cookie firmada que utiliza una política personalizada](#private-content-custom-policy-signature-cookies).  
**`CloudFront-Key-Pair-Id`**  
El ID de una clave pública de CloudFront, por ejemplo, `K2JCJMDEHXQW5F`. El ID de clave pública indica a CloudFront qué clave pública usar para validar la URL firmada. CloudFront compara la información de la firma con la información de la instrucción de política para comprobar que la URL no se ha manipulado.  
Esta clave pública debe pertenecer a un grupo de claves que tiene un signatario de confianza en la distribución. Para obtener más información, consulte [Especificación de los signatarios que pueden crear URL firmadas y cookies firmadas](private-content-trusted-signers.md).

## Ejemplos de encabezados `Set-Cookie` para políticas personalizadas
<a name="example-set-cookie-headers-custom-policy"></a>

Consulte los siguientes ejemplos de pares de encabezados `Set-Cookie`. 

Si desea utilizar un nombre de dominio alternativo como example.org en las URL, debe agregarlo a la distribución independientemente de que especifique el atributo `Domain`. Para obtener más información, consulte [Nombres de dominio alternativos (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).

**Example Ejemplo 1**  
Puede utilizar los encabezados `Set-Cookie` de una cookie firmada cuando se utiliza el nombre de dominio asociado a la distribución en las URL de los archivos.  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
```

**Example Ejemplo 2**  
Puede utilizar los encabezados `Set-Cookie` de una cookie firmada cuando se utiliza el nombre de dominio alternativo (example.org) en las URL de los archivos.  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/; Secure; HttpOnly
```

**Example Ejemplo 3**  
Puede utilizar los pares de encabezados `Set-Cookie` de una solicitud firmada cuando se utiliza el nombre de dominio asociado a la distribución en las URL de los archivos.  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=dd111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
```

**Example Ejemplo 4**  
Puede utilizar los pares de encabezados `Set-Cookie` de una solicitud firmada cuando se utiliza un nombre de dominio alternativo (example.org) asociado a la distribución en las URL de los archivos.  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/; Secure; HttpOnly
```

## Creación de una instrucción de política para una cookie firmada que utiliza una política personalizada
<a name="private-content-custom-policy-statement-cookies"></a>

Para crear una instrucción de política para una política personalizada, complete los siguientes pasos. Para consultar varias instrucciones de políticas de ejemplo que controlan el acceso a archivos de distintas maneras, consulte [Ejemplos de instrucciones de políticas para una cookie firmada que utiliza una política personalizada](#private-content-custom-policy-statement-signed-cookies-examples).<a name="private-content-custom-policy-statement-cookies-procedure"></a>

**Para crear una instrucción de política para una cookie firmada que use una política personalizada**

1. Cree la instrucción de política en el siguiente formato JSON.

   ```
   {
       "Statement": [
           {
               "Resource": "URL of the file",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime":required ending date and time in Unix time format and UTC
                   },
                   "DateGreaterThan": {
                       "AWS:EpochTime":optional beginning date and time in Unix time format and UTC
                   },
                   "IpAddress": {
                       "AWS:SourceIp": "optional IP address"
                   }
               }
           }
       ]
   }
   ```

   Tenga en cuenta lo siguiente:
   + Puede incluir una instrucción.
   + Utilice la codificación de caracteres UTF-8.
   + Incluya toda la puntuación y los nombres de parámetros exactamente como se especifica. No se aceptan abreviaturas de nombres de parámetros.
   + El orden de los parámetros de la sección `Condition` no importa.
   + Para obtener información acerca de valores para `Resource`, `DateLessThan`, `DateGreaterThan` y `IpAddress`, consulte [Valores que se especifican en la instrucción de política de una política personalizada para cookies firmadas](#private-content-custom-policy-statement-cookies-values).

1. Elimine todos los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la instrucción de la política. Es posible que tenga que incluir caracteres de escape en la cadena del código de la aplicación.

1. Codifique la instrucción de política con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html)

1. Incluya el valor resultante en el encabezado `Set-Cookie` después de `CloudFront-Policy=`.

1. Cree una firma para el encabezado `Set-Cookie` en `CloudFront-Signature` aplicando una función hash, firmando y codificando con base64 la instrucción de política. Para obtener más información, consulte [Creación de una firma para una cookie firmada que utiliza una política personalizada](#private-content-custom-policy-signature-cookies).

### Valores que se especifican en la instrucción de política de una política personalizada para cookies firmadas
<a name="private-content-custom-policy-statement-cookies-values"></a>

Al crear una instrucción de política para una política personalizada, debe especificar los siguientes valores.

**Recurso**  
La URL base, incluidas las cadenas de consulta, de haberlas:  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
Si omite el parámetro `Resource`, los usuarios podrán obtener acceso a todos los archivos asociados a cualquier distribución que esté asociada al par de claves utilizado para crear la URL firmada.
Puede especificar solo un valor en `Resource`.  
Tenga en cuenta lo siguiente:  
+ **Protocol (Protocolo)**: el valor debe comenzar con `http://` o `https://`.
+ **Query string parameters (Parámetros de cadena de consulta)**: si no tiene parámetros de cadena de consulta, omita el signo de interrogación.
+ **Wildcards (Caracteres comodín)**: puede utilizar el carácter comodín que coincide con cero o más caracteres (\$1) o el carácter comodín que coincide exactamente con un carácter (?) en cualquier lugar de la cadena. Por ejemplo, el valor:

  `https://d111111abcdef8.cloudfront.net/*game_download.zip*`

  incluiría, por ejemplo, los siguientes archivos:
  + `https://d111111abcdef8.cloudfront.net/game_download.zip`
  + `https://d111111abcdef8.cloudfront.net/example_game_download.zip?license=yes`
  + `https://d111111abcdef8.cloudfront.net/test_game_download.zip?license=temp`
+ **Alternate domain names (Nombres de dominio alternativos)**: si especifica un nombre de dominio alternativo (CNAME) en la URL, debe especificarlo al hacer referencia al archivo en la página web o aplicación. No especifique la URL de Amazon S3 para el archivo.

**DateLessThan**  
La fecha y hora de vencimiento de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). No incluya el valor entre comillas.  
Por ejemplo, 16 de marzo de 2015 a las 10:00 h UTC pasa a ser 1426500000 en formato de tiempo Unix.  
Para obtener más información, consulte [Cuándo comprueba CloudFront la fecha y hora de vencimiento de una cookie firmada](private-content-signed-cookies.md#private-content-check-expiration-cookie).

**DateGreaterThan (opcional)**  
Una fecha y hora de inicio opcionales de la URL en formato de tiempo Unix (en segundos) y hora universal coordinada (UTC). Los usuarios no pueden acceder al archivo en la fecha y hora especificadas ni antes. No incluya el valor entre comillas. 

**IpAddress (opcional)**  
La dirección IP del cliente que hace la solicitud GET. Tenga en cuenta lo siguiente:  
+ Para permitir que cualquier dirección IP obtenga acceso al archivo, omita el parámetro `IpAddress`.
+ Puede especificar una dirección IP o a un rango de direcciones IP. Por ejemplo, no puede configurar la política para permitir el acceso si la dirección IP del cliente está en uno de dos rangos separados.
+ Para permitir el acceso desde una única dirección IP, especifique:

  `"`*Dirección IP IPv*`/32"`
+ Debe especificar rangos de direcciones IP en formato estándar IPv4 CIDR (por ejemplo, `192.0.2.0/24`). Para obtener más información, consulte *RFC 4632, Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan*, [https://tools.ietf.org/html/rfc4632](https://tools.ietf.org/html/rfc4632).
**importante**  
Las direcciones IP en formato IPv6, como 2001:0db8:85a3::8a2e:0370:7334, no son compatibles. 

  Si está utilizando una política personalizada que incluya `IpAddress`, no habilite IPv6 para la distribución. Si desea restringir el acceso a algún contenido por dirección IP y admite solicitudes IPv6 de otro contenido, puede crear dos distribuciones. Para obtener más información, consulte [Habilitación de IPv6 (solicitudes de espectadores)](DownloadDistValuesGeneral.md#DownloadDistValuesEnableIPv6) en el tema [Referencia de toda la configuración de distribución](distribution-web-values-specify.md).

## Ejemplos de instrucciones de políticas para una cookie firmada que utiliza una política personalizada
<a name="private-content-custom-policy-statement-signed-cookies-examples"></a>

En los siguientes ejemplos de instrucciones de políticas, se muestra cómo controlar el acceso a un archivo específico, a todos los archivos de un directorio o a todos los archivos asociados a un ID de par de claves. Los ejemplos también muestran cómo controlar el acceso de una dirección IP individual o a un rango de direcciones IP, y cómo impedir que los usuarios utilicen la cookie firmada después de una fecha y hora específicas.

Si copia y pega cualquiera de estos ejemplos, elimine los espacios vacíos (incluidos los tabuladores y los caracteres de línea nueva), sustituya los valores por sus propios valores e incluya un carácter de línea nueva después de la llave de cierre ( \$1 ).

Para obtener más información, consulte [Valores que se especifican en la instrucción de política de una política personalizada para cookies firmadas](#private-content-custom-policy-statement-cookies-values).

**Topics**
+ [Ejemplo de instrucción de política: acceso a un archivo desde un intervalo de direcciones IP](#private-content-custom-policy-statement-signed-cookies-example-one-object)
+ [Ejemplo de instrucción de política: acceso a todos los archivos de un directorio desde un intervalo de direcciones IP](#private-content-custom-policy-statement-signed-cookies-example-all-objects)
+ [Ejemplo de instrucción de política: acceso a todos los archivos asociados con un ID de par de claves desde una dirección IP](#private-content-custom-policy-statement-signed-cookies-example-one-ip)

### Ejemplo de instrucción de política: acceso a un archivo desde un intervalo de direcciones IP
<a name="private-content-custom-policy-statement-signed-cookies-example-one-object"></a>

En la siguiente política personalizada de ejemplo de una cookie firmada se especifica que un usuario puede acceder al archivo `https://d111111abcdef8.cloudfront.net/game_download.zip` desde las direcciones IP incluidas en el intervalo `192.0.2.0/24` hasta el 1 de enero de 2023 a las 10:00 UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/game_download.zip",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

### Ejemplo de instrucción de política: acceso a todos los archivos de un directorio desde un intervalo de direcciones IP
<a name="private-content-custom-policy-statement-signed-cookies-example-all-objects"></a>

La siguiente política personalizada de ejemplo le permite crear cookies firmadas para cualquier archivo del directorio `training`, tal y como indica el carácter comodín \$1 del parámetro `Resource`. Los usuarios podrán obtener acceso al archivo desde una dirección IP incluida en el rango `192.0.2.0/24` hasta el 1 de enero de 2013 a las 10:00 h UTC:

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/training/*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

Cada cookie firmada en la que utilice esta política tendrá una URL base que identificará un archivo específico; por ejemplo:

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

### Ejemplo de instrucción de política: acceso a todos los archivos asociados con un ID de par de claves desde una dirección IP
<a name="private-content-custom-policy-statement-signed-cookies-example-one-ip"></a>

La siguiente política personalizada de ejemplo le permite establecer cookies firmadas para cualquier archivo asociado a cualquier distribución, tal y como indica el carácter comodín \$1 del parámetro `Resource`. El usuario debe utilizar la dirección IP `192.0.2.10/32`. (El valor `192.0.2.10/32` en notación CIDR se refiere a la dirección IP individual `192.0.2.10`). Los archivos solo van a estar disponibles desde el 1 de enero de 2013 a las 10:00 h UTC hasta el 2 de enero de 2013 a las 10:00 h UTC:

```
{
    "Statement": [
        {
            "Resource": "https://*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.10/32"
                },
                "DateGreaterThan": {
                    "AWS:EpochTime": 1767290400
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767376800
                }
            }
        }
    ]
}
```

Cada cookie firmada en la que utiliza esta política incluye una URL base que identifica un archivo específico de una distribución de CloudFront específica; por ejemplo:

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

La cookie firmada también incluye un ID de par de claves que se debe asociar con un grupo de claves de confianza en la distribución (d111111abcdef8.cloudfront.net) que se especifica en la URL base.

## Creación de una firma para una cookie firmada que utiliza una política personalizada
<a name="private-content-custom-policy-signature-cookies"></a>

La firma de una cookie firmada que utiliza una política personalizada es una versión de la instrucción de política a la que se le ha aplicado una función hash, firmada y codificada con base64. 

Para obtener más información y ejemplos de cómo resumir, aplicar una función hash y codificar la instrucción de política, consulte:
+ [Comandos de Linux y OpenSSL para codificación y cifrado base64](private-content-linux-openssl.md)
+ [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-custom-policy-signature-cookies-procedure"></a>

**Para crear una firma para una cookie firmada con una política personalizada**

1. Use la función hash SHA-1 y RSA para resumir y firmar la instrucción de política JSON creada en el procedimiento [Para crear una instrucción de política para una URL firmada que use una política personalizada](private-content-creating-signed-url-custom-policy.md#private-content-custom-policy-creating-policy-procedure). Utilice la versión de la instrucción de política que ya no incluye espacios vacíos pero que aún no se ha codificado con base64.

   Para la clave privada requerida por la función hash, utilice una clave privada cuya clave pública esté en un grupo de claves de confianza activo para la distribución.
**nota**  
El método que utilice para resumir y aplicar una función hash la instrucción de política depende de su lenguaje de programación y plataforma. Para ver código de muestra, consulte [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md).

1. Elimine los espacios vacíos (incluidos tabuladores y caracteres de línea nueva) de la cadena a la que se le ha aplicado una función hash y firmada.

1. Codifique la cadena con codificación base64 de MIME. Para obtener más información, consulte la [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) de *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies*.

1. Sustituya caracteres no válidos en una cadena de consulta de URL por caracteres válidos. En la siguiente tabla se muestran los caracteres válidos y no válidos.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html)

1. Incluya el valor resultante en el encabezado `Set-Cookie`, en el par nombre-valor `CloudFront-Signature=`, y vuelva a [Para establecer cookies firmadas mediante una política personalizada](#private-content-setting-signed-cookie-custom-policy-procedure) para añadir el encabezado `Set-Cookie` en `CloudFront-Key-Pair-Id`.

# Create signed cookies using PHP
<a name="signed-cookies-PHP"></a>

El siguiente ejemplo de código es similar al ejemplo de [Crear una firma de URL con PHP](CreateURL_PHP.md) en el sentido de que crea un enlace a un video. Sin embargo, en lugar de firmar la URL en el código, en este ejemplo se firman las cookies con la función `create_signed_cookies()`. El reproductor del cliente utiliza las cookies para autenticar cada solicitud a la distribución de CloudFront.

Este enfoque resulta útil para transmitir contenido, como HTTP Live Streaming (HLS) o la transmisión dinámica adaptativa a través de HTTP (DASH), donde el cliente debe realizar varias solicitudes para recuperar el manifiesto, los segmentos y los activos de reproducción relacionados. Al usar cookies firmadas, el cliente puede autenticar cada solicitud sin necesidad de generar una nueva URL firmada para cada segmento. 

**nota**  
Crear una firma de URL es solo una parte del proceso de entrega de contenido privado mediante cookies firmadas. Para obtener más información, consulte [Uso de cookies firmadas](private-content-signed-cookies.md).



**Topics**
+ [Creación de la firma RSA SHA-1](#create-rsa-sha-1signature-cookies)
+ [Creación de cookies firmadas](#create-the-signed-cookie)
+ [Código completo](#full-code-signed-cookies)

En las siguientes secciones, se desglosa el ejemplo de código en partes individuales. A continuación, encontrará el [ejemplo de código](#full-code-signed-cookies) completo.

## Creación de la firma RSA SHA-1
<a name="create-rsa-sha-1signature-cookies"></a>

Este ejemplo de código hace lo siguiente:

1. La función `rsa_sha1_sign` proporciona hashes y firma la instrucción de política. Los argumentos requeridos son una instrucción de política y la clave privada que corresponde a una clave pública que está en un grupo de claves de confianza para la distribución.

1. A continuación, la función `url_safe_base64_encode` crea una versión de la firma de URL segura.

   ```
   function rsa_sha1_sign($policy, $private_key_filename) {
       $signature = "";
       $fp = fopen($private_key_filename, "r");
       $priv_key = fread($fp, 8192);
       fclose($fp);
       $pkeyid = openssl_get_privatekey($priv_key);
       openssl_sign($policy, $signature, $pkeyid);
       openssl_free_key($pkeyid);
       return $signature;
   }
   
   function url_safe_base64_encode($value) {
       $encoded = base64_encode($value);
       return str_replace(
           array('+', '=', '/'),
           array('-', '_', '~'),
           $encoded);
   }
   ```

## Creación de cookies firmadas
<a name="create-the-signed-cookie"></a>

El siguiente código crea las cookies firmadas con los siguientes atributos de cookie: `CloudFront-Expires`, `CloudFront-Signature` y `CloudFront-Key-Pair-Id`. El código usa una política personalizada.

```
function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) {
    $policy = array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array('AWS:EpochTime' => $expires)
                )
            )
        )
    );

    if ($client_ip) {
        $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32');
    }

    $policy = json_encode($policy);
    $encoded_policy = url_safe_base64_encode($policy);
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    $encoded_signature = url_safe_base64_encode($signature);

    return array(
        'CloudFront-Policy' => $encoded_policy,
        'CloudFront-Signature' => $encoded_signature,
        'CloudFront-Key-Pair-Id' => $key_pair_id
    );
}
```

Para obtener más información, consulte [Establecimiento de cookies firmadas mediante una política personalizada](private-content-setting-signed-cookie-custom-policy.md).

## Código completo
<a name="full-code-signed-cookies"></a>

El siguiente ejemplo de código proporciona una demostración completa de la creación de cookies firmadas de CloudFront con PHP. Puede descargar el ejemplo completo desde el archivo [demo-php.zip](samples/demo-php.zip).

En el siguiente ejemplo, puede modificar el elemento `$policy Condition` para permitir los rangos de direcciones IPv4 e IPv6. Para ver un ejemplo, consulte [Uso de direcciones IPv6 en políticas de IAM](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ipv6-access.html#ipv6-access-iam) en la *Guía del usuario de Amazon Simple Storage Service*.

```
<?php

function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);
    openssl_sign($policy, $signature, $pkeyid);
    openssl_free_key($pkeyid);
    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}

function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) {
    $policy = array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array('AWS:EpochTime' => $expires)
                )
            )
        )
    );

    if ($client_ip) {
        $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32');
    }

    $policy = json_encode($policy);
    $encoded_policy = url_safe_base64_encode($policy);
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    $encoded_signature = url_safe_base64_encode($signature);

    return array(
        'CloudFront-Policy' => $encoded_policy,
        'CloudFront-Signature' => $encoded_signature,
        'CloudFront-Key-Pair-Id' => $key_pair_id
    );
}



$private_key_filename = '/home/test/secure/example-priv-key.pem';
$key_pair_id = 'K2JCJMDEHXQW5F';
$base_url = 'https://d1234.cloudfront.net';

$expires = time() + 3600; // 1 hour from now

// Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345")
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];


// For HLS manifest and segments (using wildcard)
$hls_resource = $base_url . '/sign/*';
$signed_cookies = create_signed_cookies($hls_resource, $private_key_filename, $key_pair_id, $expires, $client_ip);

// Set the cookies
$cookie_domain = parse_url($base_url, PHP_URL_HOST);
foreach ($signed_cookies as $name => $value) {
    setcookie($name, $value, $expires, '/', $cookie_domain, true, true);
}

?>

<!DOCTYPE html>
<html>
<head>
    <title>CloudFront Signed HLS Stream with Cookies</title>
</head>
<body>
    <h1>Amazon CloudFront Signed HLS Stream with Cookies</h1>
    <h2>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h2>
    
    <div id='hls-video'>
        <video id="video" width="640" height="360" controls></video>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <script>
        var video = document.getElementById('video');
        var manifestUrl = '<?php echo $base_url; ?>/sign/manifest.m3u8';
        
        if (Hls.isSupported()) {
            var hls = new Hls();
            hls.loadSource(manifestUrl);
            hls.attachMedia(video);
        }
        else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            video.src = manifestUrl;
        }
    </script>
</body>
</html>
```

En lugar de utilizar cookies firmadas, puede utilizar URL firmadas. Para obtener más información, consulte [Crear una firma de URL con PHP](CreateURL_PHP.md).

# Comandos de Linux y OpenSSL para codificación y cifrado base64
<a name="private-content-linux-openssl"></a>

Utilice los siguientes comandos de línea de comandos de Linux y OpenSSL para aplicar una función hash y firmar la instrucción de política, codificar la firma con base64 y sustituir caracteres que no sean válidos en los parámetros de cadenas de consulta de URL por caracteres válidos.

Para obtener información acerca de OpenSSL, consulte [https://www.openssl.org](https://www.openssl.org).

```
cat policy | tr -d "\n" | tr -d " \t\n\r" | openssl sha1 -sign private_key.pem | openssl base64 -A | tr -- '+=/' '-_~'
```

En el comando anterior:
+ `cat` lee el archivo `policy`.
+ `tr -d "\n" | tr -d " \t\n\r"` elimina los espacios vacíos y el carácter de nueva línea agregados por `cat`.
+ OpenSSL codifica el archivo con el hash SHA-1 y lo firma con el archivo de clave privada `private_key.pem`. La firma de clave privada puede ser RSA 2048 o ECDSA 256.
+ OpenSSL codifica en base64 la instrucción de política a la que se le ha aplicado una función hash y que se ha firmado.
+ `tr` sustituye los caracteres no válidos de los parámetros de cadenas de consulta de URL por caracteres válidos.

Para consultar más ejemplos de código que demuestren la creación de una firma, consulte [Ejemplos de código para la creación de una firma para una URL firmada](PrivateCFSignatureCodeAndExamples.md).

# Ejemplos de código para la creación de una firma para una URL firmada
<a name="PrivateCFSignatureCodeAndExamples"></a>

En esta sección se incluyen ejemplos de aplicación descargables en los que se muestra cómo crear firmas para URL firmadas. Los ejemplos están disponibles en Perl, PHP, C \$1 y Java. Puede utilizar cualquiera de los ejemplos para crear URL firmadas. El script Perl se ejecuta en plataformas Linux y macOS. El ejemplo de PHP funcionará en cualquier servidor que ejecute PHP. El ejemplo de C \$1 utiliza .NET Framework.

Para obtener un código de ejemplo en JavaScript (Node.js), consulte [Creación de URL firmadas de Amazon CloudFront en Node.js](https://aws.amazon.com/blogs/developer/creating-amazon-cloudfront-signed-urls-in-node-js/) en el blog para desarrolladores de AWS.

Para obtener un código de ejemplo en Python, consulte [Generar una URL firmada para Amazon CloudFront](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudfront.html#examples) en la *Referencia de la API de AWS SDK para Python (Boto3)* y [este código de ejemplo](https://github.com/boto/boto3/blob/develop/boto3/examples/cloudfront.rst) en el repositorio GitHub de Boto3.

**Topics**
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL con PHP](CreateURL_PHP.md)
+ [Crear una firma de URL mediante C\$1 y .NET Framework](CreateSignatureInCSharp.md)
+ [Crear una firma de URL con Java](CFPrivateDistJavaDevelopment.md)

# Crear una firma de URL con Perl
<a name="CreateURLPerl"></a>

Esta sección incluye un script Perl para plataformas Linux/Mac que puede utilizar para crear la firma para contenido privado. Para crear la firma, ejecute el script con argumentos de línea de comandos que especifiquen la URL de CloudFront, la ruta a la clave privada del signatario, el ID de la clave y una fecha de vencimiento de la URL. La herramienta también puede decodificar URL firmadas. 

**nota**  
Crear una firma de URL es solo una parte del proceso de entrega de contenido privado mediante una URL firmada. Para obtener más información acerca del proceso completo, consulte [Uso de URL firmadas](private-content-signed-urls.md). 

**Topics**
+ [Código fuente del script Perl para crear una URL firmada](#CreateURLPerlScriptSource)

## Código fuente del script Perl para crear una URL firmada
<a name="CreateURLPerlScriptSource"></a>

El siguiente código fuente Perl puede utilizarse para crear una URL firmada para CloudFront. Los comentarios del código incluyen información acerca de los conmutadores de las líneas de comandos y las características de la herramienta.

```
#!/usr/bin/perl -w

# Copyright 2008 Amazon Technologies, Inc.  Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy of the License at:
#
# https://aws.amazon.com/apache2.0
#
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.

=head1 cfsign.pl

cfsign.pl - A tool to generate and verify Amazon CloudFront signed URLs

=head1 SYNOPSIS

This script uses an existing RSA key pair to sign and verify Amazon CloudFront signed URLs

View the script source for details as to which CPAN packages are required beforehand. 

For help, try:

cfsign.pl --help

URL signing examples:

cfsign.pl --action encode --url https://images.my-website.com/gallery1.zip --policy sample_policy.json --private-key privkey.pem --key-pair-id mykey

cfsign.pl --action encode --url https://images.my-website.com/gallery1.zip --expires 1257439868 --private-key privkey.pem --key-pair-id mykey

URL decode example:

cfsign.pl --action decode --url "http//mydist.cloudfront.net/?Signature=AGO-PgxkYo99MkJFHvjfGXjG1QDEXeaDb4Qtzmy85wqyJjK7eKojQWa4BCRcow__&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovLypicmFkbS5qcGciLCJDb25kaXRpb24iOnsiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjEwLjUyLjE3LjkvMCJ9LCJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1MjUyMDgzMH19fV19Cg__&Key-Pair-Id=mykey"


To generate an RSA key pair, you can use openssl and the following commands:

# Generate a 2048 bit key pair
openssl genrsa -out private-key.pem 2048
openssl rsa -in private-key.pem -pubout -out public-key.pem


=head1 OPTIONS

=over 8

=item B<--help>

Print a help message and exits.

=item B<--action> [action]

The action to execute.  action can be one of:

  encode - Generate a signed URL (using a canned policy or a user policy)
  decode - Decode a signed URL

=item B<--url>

The URL to en/decode

=item B<--stream>

The stream to en/decode

=item B<--private-key>

The path to your private key.

=item B<--key-pair-id>

The key pair identifier.

=item B<--policy>

The CloudFront policy document.

=item B<--expires>

The Unix epoch time when the URL is to expire. If both this option and
the --policy option are specified, --policy will be used. Otherwise, this 
option alone will use a canned policy.

=back

=cut

use strict;
use warnings;

# you might need to use CPAN to get these modules.
# run perl -MCPAN -e "install <module>" to get them.
# The openssl command line will also need to be in your $PATH.
use File::Temp qw/tempfile/;
use File::Slurp;
use Getopt::Long;
use IPC::Open2;
use MIME::Base64 qw(encode_base64 decode_base64);
use Pod::Usage;
use URI;

my $CANNED_POLICY 
    = '{"Statement":[{"Resource":"<RESOURCE>","Condition":{"DateLessThan":{"AWS:EpochTime":<EXPIRES>}}}]}';

my $POLICY_PARAM      = "Policy";
my $EXPIRES_PARAM     = "Expires";
my $SIGNATURE_PARAM   = "Signature";
my $KEY_PAIR_ID_PARAM = "Key-Pair-Id";

my $verbose = 0;
my $policy_filename = "";
my $expires_epoch = 0;
my $action = "";
my $help = 0;
my $key_pair_id = "";
my $url = "";
my $stream = "";
my $private_key_filename = "";

my $result = GetOptions("action=s"      => \$action,
                        "policy=s"      => \$policy_filename,
                        "expires=i"     => \$expires_epoch,
                        "private-key=s" => \$private_key_filename,
                        "key-pair-id=s" => \$key_pair_id,
                        "verbose"       => \$verbose,
                        "help"          => \$help,
                        "url=s"         => \$url,
                        "stream=s"      => \$stream,
                    );

if ($help or !$result) {
    pod2usage(1);
    exit;
}

if ($url eq "" and $stream eq "") {
    print STDERR "Must include a stream or a URL to encode or decode with the --stream or --url option\n";
    exit;
}

if ($url ne "" and $stream ne "") {
    print STDERR "Only one of --url and --stream may be specified\n";
    exit;
}

if ($url ne "" and !is_url_valid($url)) {
    exit;
}

if ($stream ne "") {
    exit unless is_stream_valid($stream);

    # The signing mechanism is identical, so from here on just pretend we're
    # dealing with a URL
    $url = $stream;
} 

if ($action eq "encode") {
    # The encode action will generate a private content URL given a base URL, 
    # a policy file (or an expires timestamp) and a key pair id parameter
    my $private_key;
    my $public_key;
    my $public_key_file;
    
    my $policy;
    if ($policy_filename eq "") {
        if ($expires_epoch == 0) {
            print STDERR "Must include policy filename with --policy argument or an expires" . 
                          "time using --expires\n";            
        }
        
        $policy = $CANNED_POLICY;
        $policy =~ s/<EXPIRES>/$expires_epoch/g;
        $policy =~ s/<RESOURCE>/$url/g;
    } else {
        if (! -e $policy_filename) {
            print STDERR "Policy file $policy_filename does not exist\n";
            exit;
        }
        $expires_epoch = 0; # ignore if set
        $policy = read_file($policy_filename);
    }

    if ($private_key_filename eq "") {
        print STDERR "You must specific the path to your private key file with --private-key\n";
        exit;
    }

    if (! -e $private_key_filename) {
        print STDERR "Private key file $private_key_filename does not exist\n";
        exit;
    }

    if ($key_pair_id eq "") {
        print STDERR "You must specify a key pair id with --key-pair-id\n";
        exit;
    }

    my $encoded_policy = url_safe_base64_encode($policy);
    my $signature = rsa_sha1_sign($policy, $private_key_filename);
    my $encoded_signature = url_safe_base64_encode($signature);

    my $generated_url = create_url($url, $encoded_policy, $encoded_signature, $key_pair_id, $expires_epoch);


    if ($stream ne "") {
        print "Encoded stream (for use within a swf):\n" . $generated_url . "\n";
        print "Encoded and escaped stream (for use on a webpage):\n" .  escape_url_for_webpage($generated_url) . "\n"; 
    } else {
        print "Encoded URL:\n" . $generated_url . "\n";
    }
} elsif ($action eq "decode") {
    my $decoded = decode_url($url);
    if (!$decoded) {
        print STDERR "Improperly formed URL\n";
        exit;
    }

    print_decoded_url($decoded);
} else {
    # No action specified, print help.  But only if this is run as a program (caller will be empty)
    pod2usage(1) unless caller();
}

# Decode a private content URL into its component parts
sub decode_url {
    my $url = shift;

    if ($url =~ /(.*)\?(.*)/) {
        my $base_url = $1;
        my $params = $2;

        my @unparsed_params = split(/&/, $params);
        my %params = ();
        foreach my $param (@unparsed_params) {
            my ($key, $val) = split(/=/, $param);
            $params{$key} = $val;
        }

        my $encoded_signature = "";
        if (exists $params{$SIGNATURE_PARAM}) {
            $encoded_signature = $params{"Signature"};
        } else {
            print STDERR "Missing Signature URL parameter\n";
            return 0;
        }

        my $encoded_policy = "";
        if (exists $params{$POLICY_PARAM}) {
            $encoded_policy = $params{$POLICY_PARAM};
        } else {
            if (!exists $params{$EXPIRES_PARAM}) {
                print STDERR "Either the Policy or Expires URL parameter needs to be specified\n";
                return 0;    
            }
            
            my $expires = $params{$EXPIRES_PARAM};
            
            my $policy = $CANNED_POLICY;
            $policy =~ s/<EXPIRES>/$expires/g;
            
            my $url_without_cf_params = $url;
            $url_without_cf_params =~ s/$SIGNATURE_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$POLICY_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$EXPIRES_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$KEY_PAIR_ID_PARAM=[^&]*&?//g;
            
            if ($url_without_cf_params =~ /(.*)\?$/) {
                $url_without_cf_params = $1;
            }
            
            $policy =~ s/<RESOURCE>/$url_without_cf_params/g;
            
            $encoded_policy = url_safe_base64_encode($policy);
        }

        my $key = "";
        if (exists $params{$KEY_PAIR_ID_PARAM}) {
            $key = $params{$KEY_PAIR_ID_PARAM};
        } else {
            print STDERR "Missing $KEY_PAIR_ID_PARAM parameter\n";
            return 0;
        }

        my $policy = url_safe_base64_decode($encoded_policy);

        my %ret = ();
        $ret{"base_url"} = $base_url;
        $ret{"policy"} = $policy;
        $ret{"key"} = $key;

        return \%ret;
    } else {
        return 0;
    }
}

# Print a decoded URL out
sub print_decoded_url {
    my $decoded = shift;

    print "Base URL: \n" . $decoded->{"base_url"} . "\n";
    print "Policy: \n" . $decoded->{"policy"} . "\n";
    print "Key: \n" . $decoded->{"key"} . "\n";
}

# Encode a string with base 64 encoding and replace some invalid URL characters
sub url_safe_base64_encode {
    my ($value) = @_;

    my $result = encode_base64($value);
    $result =~ tr|+=/|-_~|;

    return $result;
}

# Decode a string with base 64 encoding.  URL-decode the string first
# followed by reversing any special character ("+=/") translation.
sub url_safe_base64_decode {
    my ($value) = @_;

    $value =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
    $value =~ tr|-_~|+=/|;

    my $result = decode_base64($value);

    return $result;
}

# Create a private content URL
sub create_url {
    my ($path, $policy, $signature, $key_pair_id, $expires) = @_;
    
    my $result;
    my $separator = $path =~ /\?/ ? '&' : '?';
    if ($expires) {
        $result = "$path$separator$EXPIRES_PARAM=$expires&$SIGNATURE_PARAM=$signature&$KEY_PAIR_ID_PARAM=$key_pair_id";
    } else {
        $result = "$path$separator$POLICY_PARAM=$policy&$SIGNATURE_PARAM=$signature&$KEY_PAIR_ID_PARAM=$key_pair_id";
    }
    $result =~ s/\n//g;

    return $result;
}

# Sign a document with given private key file.
# The first argument is the document to sign
# The second argument is the name of the private key file
sub rsa_sha1_sign {
    my ($to_sign, $pvkFile) = @_;
    print "openssl sha1 -sign $pvkFile $to_sign\n";

    return write_to_program($pvkFile, $to_sign);
}

# Helper function to write data to a program
sub write_to_program {
my ($keyfile, $data) = @_;
unlink "temp_policy.dat" if (-e "temp_policy.dat");
unlink "temp_sign.dat" if (-e "temp_sign.dat");

write_file("temp_policy.dat", $data);

system("openssl dgst -sha1 -sign \"$keyfile\" -out temp_sign.dat temp_policy.dat");

my $output = read_file("temp_sign.dat");

    return $output;
}

# Read a file into a string and return the string
sub read_file {
    my ($file) = @_;

    open(INFILE, "<$file") or die("Failed to open $file: $!");
    my $str = join('', <INFILE>);
    close INFILE;

    return $str;
}

sub is_url_valid {
    my ($url) = @_;

    # HTTP distributions start with http[s]:// and are the correct thing to sign
    if ($url =~ /^https?:\/\//) {
        return 1;
    } else {
        print STDERR "CloudFront requires absolute URLs for HTTP distributions\n";
        return 0;
    }
}

sub is_stream_valid {
    my ($stream) = @_;

    if ($stream =~ /^rtmp:\/\// or $stream =~ /^\/?cfx\/st/) {
        print STDERR "Streaming distributions require that only the stream name is signed.\n";
        print STDERR "The stream name is everything after, but not including, cfx/st/\n";
        return 0;
    } else {
        return 1;
    }
}

# flash requires that the query parameters in the stream name are url
# encoded when passed in through javascript, etc.  This sub handles the minimal
# required url encoding.
sub escape_url_for_webpage {
    my ($url) = @_;

    $url =~ s/\?/%3F/g;
    $url =~ s/=/%3D/g;
    $url =~ s/&/%26/g;

    return $url;
}

1;
```

# Crear una firma de URL con PHP
<a name="CreateURL_PHP"></a>

Cualquier servidor web que ejecute PHP puede utilizar este código de ejemplo de PHP para crear instrucciones de política y firmas para distribuciones de CloudFront privadas. El ejemplo completo crea una página web que funciona con enlaces de URL firmadas que reproducen una secuencia de vídeo mediante streaming de CloudFront. Puede descargar el ejemplo completo desde el archivo [demo-php.zip](samples/demo-php.zip).

**Notas**  
Crear una firma de URL es solo una parte del proceso de entrega de contenido privado mediante una URL firmada. Para obtener más información acerca de todo el proceso, consulte [Uso de URL firmadas](private-content-signed-urls.md). 
También puede crear URL firmadas mediante la clase `UrlSigner` en AWS SDK para PHP. Para obtener más información, consulte [Class UrlSigner](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.UrlSigner.html) en la *Referencia de la API de AWS SDK para PHP*.

**Topics**
+ [Creación de la firma RSA SHA-1](#sample-rsa-sign)
+ [Creación de una política predefinida](#sample-canned-policy)
+ [Crear una política personalizada](#sample-custom-policy)
+ [Ejemplo de código completo](#full-example)

En las siguientes secciones, se desglosa el ejemplo de código en partes individuales. A continuación, puede encontrar [Ejemplo de código completo](#full-example).

## Creación de la firma RSA SHA-1
<a name="sample-rsa-sign"></a>

Este ejemplo de código hace lo siguiente:
+ La función `rsa_sha1_sign` proporciona hashes y firma la instrucción de política. Los argumentos requeridos son una instrucción de política y la clave privada que corresponde a una clave pública que está en un grupo de claves de confianza para la distribución. 
+ A continuación, la función `url_safe_base64_encode` crea una versión de la firma de URL segura.

```
function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";

    // load the private key
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);

    // compute signature
    openssl_sign($policy, $signature, $pkeyid);

    // free the key from memory
    openssl_free_key($pkeyid);

    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    // replace unsafe characters +, = and / with 
    // the safe characters -, _ and ~
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}
```

El siguiente fragmento de código utiliza las funciones `get_canned_policy_stream_name()` y `get_custom_policy_stream_name()` para crear una política predefinida y personalizada. CloudFront utiliza las políticas para crear la URL para el streaming del video, incluida la especificación de la hora de vencimiento. 

A continuación, puede utilizar una política predefinida o una política personalizada para determinar cómo administrar el acceso a su contenido. Para obtener información sobre cuál elegir, consulte la sección [Decisión de utilizar políticas predefinidas o personalizadas para URL firmadas](private-content-signed-urls.md#private-content-choosing-canned-custom-policy).

## Creación de una política predefinida
<a name="sample-canned-policy"></a>

El siguiente código de ejemplo crea una instrucción de política *predefinida* para la firma. 

**nota**  
La variable `$expires` es una marca temporal fecha/hora que debe ser un número entero, no una cadena.

```
function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) {
    // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters
    $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}';
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($canned_policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($canned_policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires);
    // URL-encode the query string characters
    return $stream_name;
}
```

Para obtener más información acerca de políticas predefinidas, consulte [Creación de una URL firmada mediante una política predefinida](private-content-creating-signed-url-canned-policy.md).

## Crear una política personalizada
<a name="sample-custom-policy"></a>

El siguiente código de ejemplo crea una instrucción de política *personalizada* para la firma. 

```
function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) {
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null);
    // URL-encode the query string characters
    return $stream_name;
}
```

Para obtener más información acerca de políticas personalizadas, consulte [Creación de una URL firmada mediante una política personalizada](private-content-creating-signed-url-custom-policy.md).

## Ejemplo de código completo
<a name="full-example"></a>

El siguiente código de muestra proporciona una demostración completa de la creación de URL firmadas de CloudFront con PHP. Puede descargar el ejemplo completo desde el archivo [demo-php.zip](samples/demo-php.zip).

En el siguiente ejemplo, puede modificar el elemento `$policy` de `Condition` para permitir los rangos de direcciones IPv4 () e IPv6. Para ver un ejemplo, consulte [Uso de direcciones IPv6 en políticas de IAM](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ipv6-access.html#ipv6-access-iam) en la *Guía del usuario de Amazon Simple Storage Service*.

```
<?php

function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";

    // load the private key
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);

    // compute signature
    openssl_sign($policy, $signature, $pkeyid);

    // free the key from memory
    openssl_free_key($pkeyid);

    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    // replace unsafe characters +, = and / with the safe characters -, _ and ~
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}

function create_stream_name($stream, $policy, $signature, $key_pair_id, $expires) {
    $result = $stream;
    // if the stream already contains query parameters, attach the new query parameters to the end
    // otherwise, add the query parameters
    $separator = strpos($stream, '?') == FALSE ? '?' : '&';
    // the presence of an expires time means we're using a canned policy
    if($expires) {
        $result .= $separator . "Expires=" . $expires . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id;
    }
    // not using a canned policy, include the policy itself in the stream name
    else {
        $result .= $separator . "Policy=" . $policy . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id;
    }

    // new lines would break us, so remove them
    return str_replace('\n', '', $result);
}


function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) {
    // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters
    $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}';
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($canned_policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($canned_policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires);
    // URL-encode the query string characters
    return $stream_name;
}

function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) {
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null);
    // URL-encode the query string characters
    return $stream_name;
}


// Path to your private key.  Be very careful that this file is not accessible
// from the web!

$private_key_filename = '/home/test/secure/example-priv-key.pem';
$key_pair_id = 'K2JCJMDEHXQW5F';

// Make sure you have "Restrict viewer access" enabled on this path behaviour and using the above Trusted key groups (recommended).
$video_path = 'https://example.com/secure/example.mp4';

$expires = time() + 300; // 5 min from now
$canned_policy_stream_name = get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires);

// Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345")
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$policy =
'{'.
    '"Statement":['.
        '{'.
            '"Resource":"'. $video_path . '",'.
            '"Condition":{'.
                '"IpAddress":{"AWS:SourceIp":"' . $client_ip . '/32"},'.
                '"DateLessThan":{"AWS:EpochTime":' . $expires . '}'.
            '}'.
        '}'.
    ']' .
    '}';
$custom_policy_stream_name = get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy);

?>

<html>

<head>
    <title>CloudFront</title>
</head>

<body>
    <h1>Amazon CloudFront</h1>
    <h2>Canned Policy</h2>
    <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?></h3>
    <br />

    <div id='canned'>The canned policy video will be here: <br>
    
        <video width="640" height="360" autoplay muted controls>
        <source src="<?php echo $canned_policy_stream_name; ?>" type="video/mp4">
        Your browser does not support the video tag.
        </video>
    </div>

    <h2>Custom Policy</h2>
    <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h3>
    <div id='custom'>The custom policy video will be here: <br>

         <video width="640" height="360" autoplay muted controls>
         <source src="<?php echo $custom_policy_stream_name; ?>" type="video/mp4">
         Your browser does not support the video tag.
        </video>
    </div> 

</body>

</html>
```

Para obtener ejemplos adicionales de firmas de URL, consulte los siguientes temas:
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL mediante C\$1 y .NET Framework](CreateSignatureInCSharp.md)
+ [Crear una firma de URL con Java](CFPrivateDistJavaDevelopment.md)

En lugar de utilizar URL firmadas para crear la firma, puede utilizar cookies firmadas. Para obtener más información, consulte [Create signed cookies using PHP](signed-cookies-PHP.md).

# Crear una firma de URL mediante C\$1 y .NET Framework
<a name="CreateSignatureInCSharp"></a>

Los ejemplos de C\$1 de esta sección implementan una aplicación de ejemplo que muestra cómo crear las firmas para distribuciones privadas de CloudFront mediante instrucciones de políticas predefinidas y personalizadas. Los ejemplos incluyen funciones de utilidad basadas en el [AWS SDK para .NET](https://aws.amazon.com/sdkfornet) que pueden resultar útiles en aplicaciones .NET.

También puede crear URL firmadas y cookies firmadas mediante SDK para .NET. En la *Referencia de la API SDK para .NET*, consulte los siguientes temas:
+ **URL firmadas**: [AmazonCloudFrontUrlSigner](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudFront/TCloudFrontUrlSigner.html) 
+ **Cookies firmadas**: [AmazonCloudFrontCookieSigner](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudFront/TCloudFrontCookieSigner.html) 

Para descargar el código, diríjase a [Código de firma en C\$1](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip).

**Notas**  
Las clases `AmazonCloudFrontUrlSigner` y `AmazonCloudFrontCookieSigner` se han trasladado a un paquete independiente. Para obtener más información sobre su uso, consulte [CookieSigner and UrlSigner](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html#net-dg-v4-CookieSigner-UrlSigner) en la *Guía para desarrolladores de AWS SDK para .NET (V4)*. 
Crear una firma de URL es solo una parte del proceso de entrega de contenido privado mediante una URL firmada. Para obtener más información, consulte [Uso de URL firmadas](private-content-signed-urls.md). Para obtener más información sobre el uso de cookies firmadas, consulte [Uso de cookies firmadas](private-content-signed-cookies.md).

## Uso de una clave RSA en .NET Framework
<a name="rsa-key-sdk-net"></a>

Para utilizar una clave RSA en .NET Framework, debe convertir el archivo.pem suministrado por AWS al formato XML que utiliza el .NET Framework.

Después de la conversión, el archivo de clave privada RSA estará en el siguiente formato:

**Example Clave privada RSA en formato XML de .NET Framework**  <a name="RSAPrivateKeyXML.NETFrameworkFormat"></a>

```
<RSAKeyValue>
  <Modulus>
    wO5IvYCP5UcoCKDo1dcspoMehWBZcyfs9QEzGi6Oe5y+ewGr1oW+vB2GPB
    ANBiVPcUHTFWhwaIBd3oglmF0lGQljP/jOfmXHUK2kUUnLnJp+oOBL2NiuFtqcW6h/L5lIpD8Yq+NRHg
    Ty4zDsyr2880MvXv88yEFURCkqEXAMPLE=
  </Modulus>
  <Exponent>AQAB</Exponent>
  <P>
    5bmKDaTz
    npENGVqz4Cea8XPH+sxt+2VaAwYnsarVUoSBeVt8WLloVuZGG9IZYmH5KteXEu7fZveYd9UEXAMPLE==
  </P>
  <Q>
    1v9l/WN1a1N3rOK4VGoCokx7kR2SyTMSbZgF9IWJNOugR/WZw7HTnjipO3c9dy1Ms9pUKwUF4
    6d7049EXAMPLE==
  </Q>
  <DP>
    RgrSKuLWXMyBH+/l1Dx/I4tXuAJIrlPyo+VmiOc7b5NzHptkSHEPfR9s1
    OK0VqjknclqCJ3Ig86OMEtEXAMPLE==
  </DP>
  <DQ>
    pjPjvSFw+RoaTu0pgCA/jwW/FGyfN6iim1RFbkT4
    z49DZb2IM885f3vf35eLTaEYRYUHQgZtChNEV0TEXAMPLE==
  </DQ>
  <InverseQ>
    nkvOJTg5QtGNgWb9i
    cVtzrL/1pFEOHbJXwEJdU99N+7sMK+1066DL/HSBUCD63qD4USpnf0myc24in0EXAMPLE==</InverseQ>
  <D>
      Bc7mp7XYHynuPZxChjWNJZIq+A73gm0ASDv6At7F8Vi9r0xUlQe/v0AQS3ycN8QlyR4XMbzMLYk
      3yjxFDXo4ZKQtOGzLGteCU2srANiLv26/imXA8FVidZftTAtLviWQZBVPTeYIA69ATUYPEq0a5u5wjGy
      UOij9OWyuEXAMPLE=
   </D>
</RSAKeyValue>
```

## Método de firma de políticas predefinidas en C\$1
<a name="canned-policy-signed-url-net"></a>

El siguiente código C\$1 crea una URL firmada que utiliza una política predefinida siguiendo los pasos que se indican a continuación:
+ Crea una instrucción de política.
+ La instrucción de política aplica la función hash mediante SHA1 y firma el resultado con RSA y la clave privada cuya clave pública correspondiente se encuentra en un grupo de claves de confianza.
+ Codifica con base64 la instrucción de política a la que se le ha aplicado una función hash y firmada y sustituye caracteres especiales para que la cadena se pueda usar tranquilamente como parámetro de solicitud de URL.
+ Encadena los valores.

Para ver la implementación completa, consulte el ejemplo disponible en [Código de firma en C\$1](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip). 

**nota**  
Se devuelve `keyId` al cargar una clave pública a CloudFront. Para obtener más información, consulte ![\[6\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/callouts/6.png)[&Key-Pair-Id](private-content-creating-signed-url-canned-policy.md).

**Example : método de firma de políticas predefinidas en C\$1**  <a name="ExampleCannedPolicySigningMethod-CSharp"></a>

```
public static string ToUrlSafeBase64String(byte[] bytes)
{
    return System.Convert.ToBase64String(bytes)
        .Replace('+', '-')
        .Replace('=', '_')
        .Replace('/', '~');
}

public static string CreateCannedPrivateURL(string urlString, 
    string durationUnits, string durationNumber, string pathToPolicyStmnt, 
    string pathToPrivateKey, string keyId)
{
    // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days 
    // to expiration, 3-numberOfPreviousUnits, 4-pathToPolicyStmnt, 
    // 5-pathToPrivateKey, 6-keyId

    TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber);

    // Create the policy statement.
    string strPolicy = CreatePolicyStatement(pathToPolicyStmnt,
        urlString, 
        DateTime.Now, 
        DateTime.Now.Add(timeSpanInterval), 
        "0.0.0.0/0");
    if ("Error!" == strPolicy) return "Invalid time frame." + 
        "Start time cannot be greater than end time.";

    // Copy the expiration time defined by policy statement.
    string strExpiration = CopyExpirationTimeFromPolicy(strPolicy);

    // Read the policy into a byte buffer.
    byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy);

    // Initialize the SHA1CryptoServiceProvider object and hash the policy data.
    using (SHA1CryptoServiceProvider 
        cryptoSHA1 = new SHA1CryptoServiceProvider())
    {
        bufferPolicy = cryptoSHA1.ComputeHash(bufferPolicy);

        // Initialize the RSACryptoServiceProvider object.
        RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider();
        XmlDocument xmlPrivateKey = new XmlDocument();

        // Load your private key, which you created by converting your 
        // .pem file to the XML format that the .NET framework uses.  
        // Several tools are available. 
        xmlPrivateKey.Load(pathToPrivateKey);

        // Format the RSACryptoServiceProvider providerRSA and 
        // create the signature.
        providerRSA.FromXmlString(xmlPrivateKey.InnerXml);
        RSAPKCS1SignatureFormatter rsaFormatter = 
            new RSAPKCS1SignatureFormatter(providerRSA);
        rsaFormatter.SetHashAlgorithm("SHA1");
        byte[] signedPolicyHash = rsaFormatter.CreateSignature(bufferPolicy);

        // Convert the signed policy to URL-safe base64 encoding and 
        // replace unsafe characters + = / with the safe characters - _ ~
        string strSignedPolicy = ToUrlSafeBase64String(signedPolicyHash);

        // Concatenate the URL, the timestamp, the signature, 
        // and the key pair ID to form the signed URL.
        return urlString + 
            "?Expires=" + 
            strExpiration + 
            "&Signature=" + 
            strSignedPolicy + 
            "&Key-Pair-Id=" + 
            keyId;
    }
}
```

## Método de firma de políticas personalizadas en C\$1
<a name="custom-policy-signed-url-net"></a>

El siguiente código C\$1 crea una URL firmada que utiliza una política personalizada siguiendo los pasos que se indican a continuación:

1. Crea una instrucción de política.

1. Codifica con base64 la instrucción de política y sustituye caracteres especiales para que la cadena se pueda usar tranquilamente como parámetro de solicitud de URL.

1. La instrucción de política aplica la función hash mediante SHA1 y cifra el resultado mediante RSA y la clave privada cuya clave pública correspondiente se encuentra en un grupo de claves de confianza.

1. Codifica con base64 la instrucción de política a la que se le ha aplicado una función hash y sustituye caracteres especiales para que la cadena se pueda usar tranquilamente como parámetro de solicitud de URL.

1. Encadena los valores.

Para ver la implementación completa, consulte el ejemplo disponible en [Código de firma en C\$1](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip). 

**nota**  
Se devuelve `keyId` al cargar una clave pública a CloudFront. Para obtener más información, consulte ![\[6\]](http://docs.aws.amazon.com/es_es/AmazonCloudFront/latest/DeveloperGuide/images/callouts/6.png)[&Key-Pair-Id](private-content-creating-signed-url-canned-policy.md).

**Example : método de firma de políticas personalizadas en C\$1**  <a name="ExampleCustomPolicySigningMethod-CSharp"></a>

```
public static string ToUrlSafeBase64String(byte[] bytes)
{
    return System.Convert.ToBase64String(bytes)
        .Replace('+', '-')
        .Replace('=', '_')
        .Replace('/', '~');
}

public static string CreateCustomPrivateURL(string urlString, 
    string durationUnits, string durationNumber, string startIntervalFromNow, 
    string ipaddress, string pathToPolicyStmnt, string pathToPrivateKey, 
    string keyId)
{
    // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days 
    // to expiration, 3-numberOfPreviousUnits, 4-starttimeFromNow, 
    // 5-ip_address, 6-pathToPolicyStmt, 7-pathToPrivateKey, 8-keyId

    TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber);
    TimeSpan timeSpanToStart = GetDurationByUnits(durationUnits, 
        startIntervalFromNow);
    if (null == timeSpanToStart) 
        return "Invalid duration units." + 
            "Valid options: seconds, minutes, hours, or days";
            
    string strPolicy = CreatePolicyStatement(
        pathToPolicyStmnt, urlString, DateTime.Now.Add(timeSpanToStart), 
        DateTime.Now.Add(timeSpanInterval), ipaddress);

    // Read the policy into a byte buffer.
    byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy);

    // Convert the policy statement to URL-safe base64 encoding and 
    // replace unsafe characters + = / with the safe characters - _ ~

    string urlSafePolicy = ToUrlSafeBase64String(bufferPolicy);

    // Initialize the SHA1CryptoServiceProvider object and hash the policy data.
    byte[] bufferPolicyHash;
    using (SHA1CryptoServiceProvider cryptoSHA1 = 
        new SHA1CryptoServiceProvider())
    {
        bufferPolicyHash = cryptoSHA1.ComputeHash(bufferPolicy);

        // Initialize the RSACryptoServiceProvider object.
        RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider();
        XmlDocument xmlPrivateKey = new XmlDocument();

        // Load your private key, which you created by converting your 
        // .pem file to the XML format that the .NET framework uses.  
        // Several tools are available. 
        xmlPrivateKey.Load(pathToPrivateKey);

        // Format the RSACryptoServiceProvider providerRSA 
        // and create the signature.
        providerRSA.FromXmlString(xmlPrivateKey.InnerXml);
        RSAPKCS1SignatureFormatter RSAFormatter = 
            new RSAPKCS1SignatureFormatter(providerRSA);
        RSAFormatter.SetHashAlgorithm("SHA1");
        byte[] signedHash = RSAFormatter.CreateSignature(bufferPolicyHash);

        // Convert the signed policy to URL-safe base64 encoding and 
        // replace unsafe characters + = / with the safe characters - _ ~
        string strSignedPolicy = ToUrlSafeBase64String(signedHash);

        return urlString + 
            "?Policy=" + 
            urlSafePolicy + 
            "&Signature=" + 
            strSignedPolicy + 
            "&Key-Pair-Id=" + 
            keyId;
    }
}
```

## Métodos de utilidades para generar firmas
<a name="utility-methods-signed-url"></a>

Los siguientes métodos obtienen la instrucción de política de un archivo y analizan intervalos de tiempo para generar firmas.

**Example : métodos de utilidades para generar firmas**  <a name="UtilityMethodsForSignatureGeneration"></a>

```
public static string CreatePolicyStatement(string policyStmnt, 
   string resourceUrl, 
   DateTime startTime, 
   DateTime endTime, 
   string ipAddress)
   
{
   // Create the policy statement.
   FileStream streamPolicy = new FileStream(policyStmnt, FileMode.Open, FileAccess.Read);
   using (StreamReader reader = new StreamReader(streamPolicy))
   {
      string strPolicy = reader.ReadToEnd();

      TimeSpan startTimeSpanFromNow = (startTime - DateTime.Now);
      TimeSpan endTimeSpanFromNow = (endTime - DateTime.Now);
      TimeSpan intervalStart = 
         (DateTime.UtcNow.Add(startTimeSpanFromNow)) - 
         new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
      TimeSpan intervalEnd = 
         (DateTime.UtcNow.Add(endTimeSpanFromNow)) - 
         new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

      int startTimestamp = (int)intervalStart.TotalSeconds; // START_TIME
      int endTimestamp = (int)intervalEnd.TotalSeconds;  // END_TIME

      if (startTimestamp > endTimestamp)
         return "Error!";

      // Replace variables in the policy statement.
      strPolicy = strPolicy.Replace("RESOURCE", resourceUrl);
      strPolicy = strPolicy.Replace("START_TIME", startTimestamp.ToString());
      strPolicy = strPolicy.Replace("END_TIME", endTimestamp.ToString());
      strPolicy = strPolicy.Replace("IP_ADDRESS", ipAddress);
      strPolicy = strPolicy.Replace("EXPIRES", endTimestamp.ToString());
      return strPolicy;
   }   
}

public static TimeSpan GetDuration(string units, string numUnits)
{
   TimeSpan timeSpanInterval = new TimeSpan();
   switch (units)
   {
      case "seconds":
         timeSpanInterval = new TimeSpan(0, 0, 0, int.Parse(numUnits));
         break;
      case "minutes":
         timeSpanInterval = new TimeSpan(0, 0, int.Parse(numUnits), 0);
         break;
      case "hours":
         timeSpanInterval = new TimeSpan(0, int.Parse(numUnits), 0 ,0);
         break;
      case "days":
         timeSpanInterval = new TimeSpan(int.Parse(numUnits),0 ,0 ,0);
         break;
      default:
         Console.WriteLine("Invalid time units;" + 
            "use seconds, minutes, hours, or days");
         break;
   }
   return timeSpanInterval;
}

private static TimeSpan GetDurationByUnits(string durationUnits, 
   string startIntervalFromNow)
{
   switch (durationUnits)
   {
      case "seconds":
         return new TimeSpan(0, 0, int.Parse(startIntervalFromNow));
      case "minutes":
         return new TimeSpan(0, int.Parse(startIntervalFromNow), 0);
      case "hours":
         return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0);
      case "days":
         return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0, 0);
      default:
         return new TimeSpan(0, 0, 0, 0);
   }
}

public static string CopyExpirationTimeFromPolicy(string policyStatement)
{
   int startExpiration = policyStatement.IndexOf("EpochTime");
   string strExpirationRough = policyStatement.Substring(startExpiration + 
      "EpochTime".Length);
   char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
         
   List<char> listDigits = new List<char>(digits);
   StringBuilder buildExpiration = new StringBuilder(20);
         
   foreach (char c in strExpirationRough)
   {
      if (listDigits.Contains(c))
         buildExpiration.Append(c);
   }
   return buildExpiration.ToString();   
}
```

Véase también
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL con PHP](CreateURL_PHP.md)
+ [Crear una firma de URL con Java](CFPrivateDistJavaDevelopment.md)

# Crear una firma de URL con Java
<a name="CFPrivateDistJavaDevelopment"></a>

Además del siguiente ejemplo de código, puede utilizar [la clase de utilidad `CloudFrontUrlSigner` de AWS SDK para Java (versión 1)](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/CloudFrontUrlSigner.html) para crear [URL firmadas de CloudFront](private-content-signed-urls.md).

Para ver más ejemplos, consulte [Create signed URLs and cookies using an AWS SDK](https://docs.aws.amazon.com/code-library/latest/ug/cloudfront_example_cloudfront_CloudFrontUtilities_section.html) en la *biblioteca de códigos de ejemplos de códigos de AWS SDK*. 

**nota**  
La creación de una URL firmada es solo una parte del proceso de [entrega de contenido privado con CloudFront](PrivateContent.md). Para obtener más información acerca de todo el proceso, consulte [Uso de URL firmadas](private-content-signed-urls.md).

En el ejemplo siguiente se muestra cómo crear una URL firmada de CloudFront.

**Example Política de Java y métodos de cifrado de firma**  <a name="ExampleJavaPolicyAndSignatureEncryptionMethods"></a>

```
package org.example;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import software.amazon.awssdk.services.cloudfront.CloudFrontUtilities;
import software.amazon.awssdk.services.cloudfront.model.CannedSignerRequest;
import software.amazon.awssdk.services.cloudfront.url.SignedUrl;

public class Main {

    public static void main(String[] args) throws Exception {
        CloudFrontUtilities cloudFrontUtilities = CloudFrontUtilities.create();
        Instant expirationDate = Instant.now().plus(7, ChronoUnit.DAYS);
        String resourceUrl = "https://a1b2c3d4e5f6g7.cloudfront.net";
        String keyPairId = "K1UA3WV15I7JSD";
        CannedSignerRequest cannedRequest = CannedSignerRequest.builder()
                .resourceUrl(resourceUrl)
                .privateKey(new java.io.File("/path/to/private_key.pem").toPath())
                .keyPairId(keyPairId)
                .expirationDate(expirationDate)
                .build();
        SignedUrl signedUrl = cloudFrontUtilities.getSignedUrlWithCannedPolicy(cannedRequest);
        String url = signedUrl.url();
        System.out.println(url);

    }
}
```

Véase también:
+ [Crear una firma de URL con Perl](CreateURLPerl.md)
+ [Crear una firma de URL con PHP](CreateURL_PHP.md)
+ [Crear una firma de URL mediante C\$1 y .NET Framework](CreateSignatureInCSharp.md)