

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Client-side cifrado a nivel de campo
<a name="field-level-encryption"></a>

El cifrado a nivel de campo (FLE) del lado del cliente de Amazon DocumentDB le permite cifrar la información confidencial de las aplicaciones cliente antes de transferirlos a un clúster de Amazon DocumentDB. La información confidencial permanece cifrada cuando se almacenan y procesan en un clúster y se descifran en la aplicación cliente cuando se recuperan.

**Topics**
+ [Introducción](#fle-getting-started)
+ [Consultas en el FLE del lado del cliente](#fle-querying)

## Introducción
<a name="fle-getting-started"></a>

La configuración inicial del FLE del lado del cliente en Amazon DocumentDB es un proceso de cuatro pasos que incluye la creación de una clave de cifrado, la asociación de un rol a la aplicación, la configuración de la aplicación y la definición de la operación CRUD con las opciones de cifrado.

**Topics**
+ [Paso 1: crear las claves de cifrado](#fle-step-create-key)
+ [Paso 2: asociar un rol a la aplicación](#fle-step-associate-role)
+ [Paso 3: configurar la aplicación](#fle-step-config-app)
+ [Paso 4: definir una operación CRUD](#fle-step-crud-ops)
+ [Ejemplo: archivo de configuración de cifrado a nivel de campo del lado del cliente](#fle-config-example)

### Paso 1: crear las claves de cifrado
<a name="fle-step-create-key"></a>

Con él AWS Key Management Service, cree una clave simétrica gestionada por el cliente que cifre y descifre el campo de datos confidenciales y concédale los permisos de uso de IAM necesarios. AWS KMS almacena la clave gestionada por el cliente, que se utiliza para cifrar las claves de datos. Almacenar la clave gestionada por el cliente AWS KMS refuerza su postura de seguridad. La clave de datos es la clave secundaria, que se almacena en una colección de Amazon DocumentDB y es necesaria para cifrar los campos confidenciales antes de almacenar el documento en Amazon DocumentDB. La clave gestionada por el cliente cifra la clave de datos, que a su vez cifra y descifra sus datos. Si usas un clúster global, puedes crear una clave multirregional que los distintos roles de servicio puedan usar en diferentes regiones.

Para obtener más información sobre la clave AWS Key Management Service, incluida la forma de crear una clave, consulta [AWS Key Management Service los conceptos ](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) en la Guía para *AWS Key Management Service * desarrolladores.

### Paso 2: asociar un rol a la aplicación
<a name="fle-step-associate-role"></a>

Cree una política de IAM con AWS KMS los permisos adecuados. Esta política permite a las identidades de IAM a las que está asociada cifrar y descifrar la clave de KMS especificada en el campo de recursos. La aplicación asume esta función de IAM con la que se autentica. AWS KMS

El aspecto de la respuesta debe ser parecido al siguiente:

```
{ "Effect": "Allow",
"Action": ["kms:Decrypt", "kms:Encrypt"],
"Resource": "Customer Key ARN"
}
```

### Paso 3: configurar la aplicación
<a name="fle-step-config-app"></a>

Ha definido una clave gestionada por el cliente AWS KMS y ha creado una función de IAM con los permisos necesarios para acceder a ella. Importe estos paquetes necesarios.

```
import boto3
import json
import base64
from pymongo import MongoClient
from pymongo.encryption import (Algorithm,
                                ClientEncryption)
```

```
# create a session object: 
my_session = boto3.session.Session()

# get access_key and secret_key programmatically using get_frozen_credentials() method:
current_credentials = my_session.get_credentials().get_frozen_credentials()
```

1. Especifique `aws` el tipo AWS KMS de proveedor e introduzca las credenciales de la cuenta que recuperó en el paso anterior.

   ```
   provider = "aws"
   kms_providers = {
       provider: {
           "accessKeyId": current_credentials.access_key,
           "secretAccessKey": current_credentials.secret_key
       }
   }
   ```

1. Especifique la clave gestionada por el cliente para cifrar la clave de datos:

   ```
   customer_key = {
   “region”: “AWS region of the customer_key”,
       “key”: “customer_key ARN”
   }
   
   key_vault_namespace = "encryption.dataKeys"
   
   key_alt_name = 'TEST_DATA_KEY'
   ```

1. Configure el MongoClient objeto:

   ```
   client = MongoClient(connection_string)
   
   coll = client.test.coll
   coll.drop()
   
   client_encryption = ClientEncryption(
       kms_providers, # pass in the kms_providers variable from the previous step
       key_vault_namespace = key_vault_namespace,
       client,
       coll.codec_options
   )
   ```

1. Genere su clave de datos:

   ```
   data_key_id = client_encryption.create_data_key(provider,
       customer_key,
       key_alt_name = [key_alt_name])
   ```

1. Recupera tu clave de datos existente:

   ```
   data_key = DataKey("aws",
       master_key = customer_key)
   key_id = data_key["_id"]
   data_key_id = client[key_vault_namespace].find_one({"_id": key_id})
   ```

### Paso 4: definir una operación CRUD
<a name="fle-step-crud-ops"></a>

Defina la operación CRUD con opciones de cifrado.

1. Defina la colección para write/read /eliminar un solo documento:

   ```
   coll = client.gameinfo.users
   ```

1. Cifrado explícito: cifra los campos e inserta:
**nota**  
Debe proporcionarse exactamente uno de los siguientes valores: “key\_id” o “key\_alt\_name”.

   ```
   encrypted_first_name = client_encryption.encrypt(
       "Jane",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
       key_id=data_key_id
   )
   encrypted_last_name = client_encryption.encrypt(
       "Doe",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
       key_id=data_key_id
   )
   encrypted_dob = client_encryption.encrypt(
       "1990-01-01",
       Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Random,
       key_id=data_key_id
   )
   
   coll.insert_one(
       {"gamerTag": "jane_doe90",
       "firstName": encrypted_first_name,
       "lastName": encrypted_last_name,
       "dateOfBirth":encrypted_dob,
       "Favorite_games":["Halo","Age of Empires 2","Medal of Honor"]
   })
   ```

### Ejemplo: archivo de configuración de cifrado a nivel de campo del lado del cliente
<a name="fle-config-example"></a>

Para utilizar el ejemplo siguiente, sustituya {{placeholder}} con su propia información.

```
# import python packages:
import boto3
import json
import base64
from pymongo import MongoClient
from pymongo.encryption import (Algorithm,
                                ClientEncryption)

def main():
    
    # create a session object:
    my_session = boto3.session.Session()
    
    # get aws_region from session object:
    aws_region = my_session.region_name
    
    # get access_key and secret_key programmatically using get_frozen_credentials() method:
    current_credentials = my_session.get_credentials().get_frozen_credentials()
    provider = "aws"
    
    # define the kms_providers which is later used to create the Data Key:
    kms_providers = {
        provider: {
            "accessKeyId": current_credentials.access_key,
            "secretAccessKey": current_credentials.secret_key
        }
    }
    
    # enter the kms key ARN. Replace the example ARN value.
    kms_arn = "{{arn:aws:kms:us-east-1:123456789:key/abcd-efgh-ijkl-mnop}}"
    customer_key = {
        "region": aws_region,
        "key":kms_arn
    }

    # secrets manager is used to store and retrieve user credentials for connecting to an Amazon DocumentDB cluster. 
    # retrieve the secret using the secret name. Replace the example secret key.
    secret_name = "{{/dev/secretKey}}"
    docdb_credentials = json.loads(my_session.client(service_name = 'secretsmanager', region_name = "us-east-1").get_secret_value(SecretId = secret_name)['SecretString'])

    connection_params = '/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'
    conn_str = 'mongodb://' + docdb_credentials["username"] + ':' + docdb_credentials["password"] + '@' + docdb_credentials["host"] + ':' + str(docdb_credentials["port"]) + connection_params
    client = MongoClient(conn_str) 

    coll = client.test.coll
    coll.drop()
    
    # store the encryption data keys in a key vault collection (having naming convention as db.collection):
    key_vault_namespace = "encryption.dataKeys"
    key_vault_db_name, key_vault_coll_name = key_vault_namespace.split(".", 1)

    # set up the key vault (key_vault_namespace) for this example:
    key_vault = client[key_vault_db_name][key_vault_coll_name]
    key_vault.drop()
    key_vault.create_index("keyAltNames", unique=True)

    client_encryption = ClientEncryption(
        kms_providers,
        key_vault_namespace,
        client,
        coll.codec_options)
    
    # create a new data key for the encrypted field:
    data_key_id = client_encryption.create_data_key(provider, master_key=customer_key, key_alt_names=["some_key_alt_name"], key_material = None)
    
    # explicitly encrypt a field:
    encrypted_first_name = client_encryption.encrypt(
    "Jane",
    Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
    key_id=data_key_id
    )
    coll.insert_one(
    {"gamerTag": "jane_doe90",
    "firstName": encrypted_first_name
    })
    doc = coll.find_one()
    print('Encrypted document: %s' % (doc,))
    
    # explicitly decrypt the field:
    doc["firstName"] = client_encryption.decrypt(doc["firstName"])
    print('Decrypted document: %s' % (doc,))
    
    # cleanup resources:
    client_encryption.close()
    client.close()
    
if __name__ == "__main__":
    main()
```

## Consultas en el FLE del lado del cliente
<a name="fle-querying"></a>

Amazon DocumentDB solo admite consultas de igualdad con valores cifrados con FLE del lado del cliente.

Por ejemplo, para consultar documentos en los que la puntuación de jugador cifrada sea igual a 500, el cliente utiliza un método de cifrado explícito para cifrar el valor de la consulta:

```
encrypted_gamerscore_filter = client_encryption.encrypt(
    500,
    Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
    key_id=data_key_id
)

coll.find( {
    "gamerscore" : { "$eq" : encrypted_gamerscore_filter }
} )
```