

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Client-side chiffrement au niveau du champ
<a name="field-level-encryption"></a>

Le chiffrement au niveau du champ (FLE) côté client Amazon DocumentDB vous permet de chiffrer les données sensibles dans vos applications clientes avant qu'elles ne soient transférées vers un cluster Amazon DocumentDB. Les données sensibles restent cryptées lorsqu'elles sont stockées et traitées dans un cluster et sont déchiffrées dans l'application cliente lorsqu'elles sont récupérées.

**Topics**
+ [Prise en main](#fle-getting-started)
+ [Interrogation dans un fichier FLE côté client](#fle-querying)

## Prise en main
<a name="fle-getting-started"></a>

La configuration initiale du FLE côté client dans Amazon DocumentDB est un processus en quatre étapes qui comprend la création d'une clé de chiffrement, l'association d'un rôle à l'application, la configuration de l'application et la définition du fonctionnement du CRUD avec des options de chiffrement.

**Topics**
+ [Étape 1 : Création des clés de chiffrement](#fle-step-create-key)
+ [Étape 2 : associer un rôle à l'application](#fle-step-associate-role)
+ [Étape 3 : Configuration de l'application](#fle-step-config-app)
+ [Étape 4 : Définition d'une opération CRUD](#fle-step-crud-ops)
+ [Exemple : fichier de configuration du chiffrement des champs côté client](#fle-config-example)

### Étape 1 : Création des clés de chiffrement
<a name="fle-step-create-key"></a>

À l'aide de AWS Key Management Service, créez une clé symétrique utilisée pour chiffrer et déchiffrer le champ de données sensibles et fournissez-lui les autorisations d'utilisation IAM nécessaires. AWS KMS stocke la clé client (CK) qui est utilisée pour chiffrer les clés de données (DKs). Stockez la clé client dans KMS pour renforcer votre niveau de sécurité. La clé de données est la clé secondaire qui est stockée dans une collection Amazon DocumentDB et qui est requise pour chiffrer les champs sensibles avant de stocker le document dans Amazon DocumentDB. La clé client chiffre la clé de données qui, à son tour, chiffre et déchiffre vos données. Si vous utilisez un cluster mondial, vous pouvez créer une clé multirégionale qui peut être utilisée par différents rôles de service dans différentes régions.

Pour plus d'informations sur le AWS Key Management Service, notamment sur la façon de créer une clé, consultez le [Guide du développeur du service de gestion des AWS clés](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html).

### Étape 2 : associer un rôle à l'application
<a name="fle-step-associate-role"></a>

Créez une politique IAM avec les AWS KMS autorisations appropriées. Cette politique permet aux identités IAM auxquelles elle est attachée de chiffrer et de déchiffrer la clé KMS spécifiée dans le champ de ressource. Votre application assume ce rôle IAM pour s'authentifier. AWS KMS

La politique doit ressembler à ceci :

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

### Étape 3 : Configuration de l'application
<a name="fle-step-config-app"></a>

À ce jour, vous avez défini une clé client, créé un rôle IAM et lui avez fourni les autorisations IAM appropriées pour accéder à la clé client. AWS KMS Importez les packages obligatoires.

```
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. Spécifiez « aws » comme type de fournisseur KMS et entrez les informations d'identification de votre compte qui ont été récupérées à l'étape précédente.

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

1. Spécifiez la clé client qui est utilisée pour chiffrer la clé de données :

   ```
   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. Configurez MongoClient l'objet :

   ```
   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. Générez votre clé de données :

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

1. Récupérez votre clé de données existante :

   ```
   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})
   ```

### Étape 4 : Définition d'une opération CRUD
<a name="fle-step-crud-ops"></a>

Définissez l'opération CRUD avec les options de chiffrement.

1. Définissez la collection pour write/read /supprimer un seul document :

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

1. Chiffrement explicite : cryptez les champs et insérez :
**Note**  
Exactement l'un des « key\_id » ou « key\_alt\_name » doit être fourni.

   ```
   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"]
   })
   ```

### Exemple : fichier de configuration du chiffrement des champs côté client
<a name="fle-config-example"></a>

Dans l'exemple suivant, remplacez chacune {{placeholder}} par vos propres informations.

```
# 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()
```

## Interrogation dans un fichier FLE côté client
<a name="fle-querying"></a>

Amazon DocumentDB prend uniquement en charge les requêtes d'égalité avec des valeurs chiffrées FLE côté client.

Par exemple, pour rechercher des documents dont le score de joueur chiffré est égal à 500, le client utilise une méthode de cryptage explicite pour chiffrer la valeur de la requête :

```
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 }
} )
```