Le Blog Amazon Web Services
Comment masquer des données sensibles avec une solution de tokenisation serverless
La sécurité et la conformité sont les priorités majeures de nos clients quelles que soient leurs industries et leur localisation. Les réglementions des industries et des gouvernements évoluent fréquemment et les sociétés doivent réagir rapidement pour rester en conformité. Dans de nombreuses situations il est prudent d’obfusquer les données pour réduire leur risque d’exposition, tout en améliorant la capacité d’innovation. Cet article traite de l’obfuscation de données (« data obfuscation », en anglais) et de son usage pour réduire les risques d’accès non-autorisés. Cette technique permet aussi de simplifier la conformité PCI-DSS en réduisant le nombre de composants auxquels elle s’applique.
Comparaison entre la tokenisation et le chiffrement
Le chiffrement et la tokenisation sont deux choses bien distinctes. Le chiffrement utilise un algorithme pour transformer un texte en clair en texte chiffré. Cela nécessite un algorithme et une clé de chiffrement pour pouvoir chiffrer et déchiffrer le texte. La tokenisation transforme une donnée en une chaîne de caractères aléatoires appelée un jeton (token). Cette chaîne de caractères qui constitue le jeton n’a aucune relation avec les données originelles. Les jetons servent comme une référence aux données originelles, mais ne peuvent pas être utilisés pour recalculer ces données.
A l’inverse du chiffrement, la tokenisation n’emploie aucune fonction mathématique pour transformer les données sensibles en un jeton. Elle utilise une base de données, appelée coffre à jeton (« token vault », en anglais) qui contient la relation entre le jeton et la donnée à protéger. La donnée contenue dans le coffre à jeton est à son tour protégée, souvent à l’aide de mécanismes de chiffrement. Le jeton est utilisé dans les applications comme un substitut aux données d’origine.
Par exemple, dans le traitement récurrent de paiements par carte de crédit, le jeton est présenté au coffre à jeton qui utilise son index pour récupérer la donnée originelle est requise dans le traitement de l’autorisation de paiement. Plus récemment, les jetons sont utilisés pour protéger d’autres données personnelles, tels que les numéros de sécurité sociale, numéros de téléphone, ou adresses mail.
Vue d’ensemble
Cet article illustre comment concevoir une solution de tokenisation sécurisée, fiable, évolutive et à faible coût. Elle peut être intégrée avec des applications pour générer des jetons, stocker les données sensibles chiffrées dans un coffre à jeton et échanger un jeton contre les données originelles.
Prenons un exemple où un analyste de données a besoin d’accéder une base de données clients. Cette base de données contient le nom du client, son numéro de sécurité sociale, son numéro de carte de crédit, ainsi que son historique d’achat et ses préférences. Certaines de ces informations sont considérées comme sensibles. Pour leur appliquer la politique de sécurité des informations requise, vous devez mettre en œuvre des méthodes telles que l’accès limité par colonnes de la base de données, le contrôle d’accès basé sur des rôles, le chiffrement par colonne, et garantir la protection contre l’accès non-autorisé. Rendre cette base accessible à notre analyste de données nécessite une gestion complexe des stratégies de sécurité sur une granularité faible. La tokenisation remplace les données sensibles par un jeton aléatoire unique, qui est stocké dans une base de données applicative. Cela simplifie et diminue le coût de la gestion d’accès, et renforce la protection des données.
Procédure pas à pas
Cette application en mode serverless utilise les services Amazon API Gateway, AWS Lambda, Amazon Cognito, Amazon DynamoDB, et le magasin de clé AWS KMS.
Le client s’authentifie (étape 1 dans le schéma ci-dessus) à l’aide d’Amazon Cognito et reçoit un jeton d’authentification Cognito (étape 2). Celui-ci est utilisé pour autoriser les appels à la fonction Lambda Customer Order (étape 3, 4 et 5). Il ne doit pas être confondu avec le jeton d’obfuscation.
Cette fonction appelle la couche Lambda (« Lambda layer », en anglais) de tokenisation, lui passant les informations sensibles contenues dans la requête du client. Cette couche fournit la logique de génération de jeton aléatoire ainsi que le stockage des données sensibles chiffrées dans une base de données. Cette couche Lambda appelle KMS pour obtenir une clé de chiffrement (6). Elle utilise la librairie du client de chiffrement DynamoDB (7) pour chiffrer le texte originel et enregistrer le texte chiffré (8) dans la base de données.
La fonction Lambda récupère le jeton généré dans la réponse de la couche de tokenisation. Celui-ci est ensuite stocké dans la base de données applicative (9) pour être utilisé plus tard.
AWS KMS facilite la création et la gestion des clés de chiffrement. Il fournit les mécanismes de journalisation de l’utilisation des clés pour vous permettre d’assurer vos besoins en matière de réglementation et de conformité.
Quand on utilise le client de chiffrement de DynamoDB, il est important de bien choisir le fournisseur de matériaux de chiffrement (cryptographic material provider ou (CMP), en anglais). Le CMP détermine comment les clés de chiffrement et de signature sont générées, ainsi que si un nouveau matériel de clé doit être généré pour chaque élément ou s’il peut être réutilisé. Il définit aussi quels algorithmes de signature et de chiffrement sont utilisés. Pour sélectionner un CMP pour votre application, référez-vous à cette documentation.
La solution actuelle choisit le Fournisseur de matériaux KMS Direct comme CMP. Ce CMP retourne une clé de chiffrement unique et une clé de signature unique pour chaque élément de la table DynamoDB. Il fait donc appel à AWS KMS à chaque fois que vous chiffrez ou déchiffrez un élément.
- A chaque chiffrement d’un élément de la table DynamoDB, le Fournisseur de matériaux KMS Direct demande à AWS KMS de générer une clé de donnée unique (data key) depuis une clé principale client ou customer master key (CMK) symétrique que vous spécifiez. Il utilise ensuite cette clé de données pour générer une clé de chiffrement et une clé de signature, qu’il vous retourne ensuite, ainsi que la clé de donnée chiffrée, qui est enregistrée dans l’attribut de description du matériau de cet élément de la table.
- Le chiffreur d’élément ou item encryptor utilise les clés de chiffrement et de signature, en les supprimant de la mémoire dès que possible. Seule la clé de donnée chiffrée est stockée avec l’élément de la table.
- Pour régénérer le matériau de déchiffrement, le Fournisseur de matériaux KMS Direct demande à AWS KMS de déchiffrer la clé de donnée. Ensuite, il dérive de nouveau les clés de chiffrement et de signature, et les retourne au chiffreur d’élément.
Le chiffreur d’élément vérifie l’intégrité de l’élément et ensuite le déchiffre. Il supprime aussi les attributs de description de matériau et de signature. Le résultat est un élément DynamoDB en texte brut.
Pour d’avantage de sécurité, notre exemple crée une fonction Lambda au sein d’un VPC, protégée par un groupe de sécurité (ou security group) n’autorisant que les requêtes HTTPS en provenance d’adresses IPs privées. La fonction Lambda se connecte à DynamoDB et à AWS KMS à l’aide de points de terminaison VPC (VPC endpoints) pour éviter de transférer des données via l’internet. Les connexions avec DynamoDB avec un service gateway endpoint et à AWS KMS avec un interface endpoint fournissent une connexion hautement disponible et sécurisée.
En outre, nous pouvons attacher une stratégie aux points de terminaison VPC (endpoint policies). Une telle stratégie permet de garantir que uniquement les opérations autorisées sur AWS KMS et DynamoDB peuvent être réalisées sur cette connexion, . Pour contrôler la gestion des clés, on associe à clé principale KMS (Customer Master Key ou CMK, en anglais) une stratégie de type “stratégie basée sur les ressources” (resource-based policy). Cette dernière autorise la couche Lambda à générer les clés de données, mais restreint les activités d’administration sur la clé principale. Pour déployer cette solution, suivez les instructions contenues dans le dépôt GitHub aws-serverless-tokenization. L’AWS Serverless Application Model (AWS SAM) vous permet de déployer rapidement cette solution dans votre compte AWS.
Comprendre le code
Cette solution utilise le package tokenizer, qui est déployé au sein d’une couche Lambda. Il utilise Python UUID4 pour générer des valeurs aléatoires. En option, vous pouvez changer la logique contenue dans hash_gen.py pour inclure votre propre mécanisme de tokenisation. Par exemple, vous pourriez souhaiter générer des jetons de même longueur que le texte originel, afin de préserver les formats dans les jetons générés.
Le fichier ddb_encrypt_item.py contient la logique de chiffrement des éléments DynamoDB et utilise la librairie du client de chiffrement DynamoDB. Pour plus d’information sur cette librairie, référez-vous à cette documentation.
La logique applicative utilise trois méthodes :
encrypt_item
chiffre le texte brut à l’aide d’AWS KMS et de la clé principale (CMK). Dans le champsAttributeActions
, vous pouvez préciser si vous ne voulez pas chiffrer une portion du texte brut. Par exemple, vous pouvez exclure certaines clés des entrées JSON des actions de chiffrement, comme ACCOUNT_ID dans l’extrait ci-dessous.encrypt_item
nécessite une clé de partition (partition key) pour indexer le texte chiffré dans DynamoDB. On utilise le jeton UUID comme clé de partition. Celui-ci est généré à l‘étape précédente par la fonctionget_uuid
contenue dans hash_gen.py.
def encrypt_item (plaintext_item,table_name):
table = boto3.resource('dynamodb').Table(table_name)
aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
actions = AttributeActions(
default_action=CryptoAction.ENCRYPT_AND_SIGN,
attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})
encrypted_table = EncryptedTable(
table=table,
materials_provider=aws_kms_cmp,
attribute_actions=actions
)
response = encrypted_table.put_item(Item=plaintext_item)
get_decrypted_item
retourne le texte déchiffré pour une clé de partition donnée. Par exemple, cela permet de récupérer la valeur en clair correspondant au jeton UUID dans la base de données chiffrées servant de coffre à jeton.get_Item
permet de récupérer une valeur chiffrée, par exemple le texte chiffré stocké dans la base DynamoDB pour une clé de partition donnée.
Le SDK dynamodb-encryption-sdk nécessite des librairies de chiffrement qui sont dépendantes des plateformes et qui doivent être installées pour chaque système d’exploitation. L’environnement d’exécution Lambda étant basé sur Amazon Linux, vous devez donc installer ces librairies pour Amazon Linux. Pour ce faire, utilisez le script get_AMI_packages_cryptography.sh pour télécharger l’image docker, installer les dépendances dans cette image et exporter les fichiers qui seront utilisés par la couche Lambda.
Si vous traitez des éléments DynamoDB à une haute fréquence et un large volume, vous pourriez être amenés à dépasser les quotas de nombre requêtes par seconde d’AWS KMS, au risque de causer des retards de traitements. Vous pouvez utiliser des outils tels que JMeter pour évaluer le débit d’AWS KMS requis sur la base du trafic attendu pour cette application serverless. Si vous devez surpasser un quota de service, vous pouvez demander une augmentation de ce quota en utilisant la console des Quotas de Service ou l’opération RequestServiceQuotaIncrease. Pour plus de détails, référez-vous au chapitre Demander une augmentation de quota dans le guide utilisateur des quotas de service. Si les quotas de service AWS KMS ne sont pas disponibles dans votre région AWS, créez une demande de support dans AWS Support Center.
Après avoir suivi cette procédure pas à pas, afin d’éviter d’encourir des frais futurs, pensez à supprimer toutes les ressources créées en suivant l’étape 7 du fichier README.
Conclusion
Cet article illustre comment utiliser des services serverless AWS pour concevoir une solution de tokenisation fiable, sécurisée et économique. Elle peut être intégrée avec des applications pour protéger des données sensibles et gérer l’accès en utilisant des contrôles stricts avec moins de charges opérationnelles.
Article original rédigé en anglais par James Beswick (Principal Developer Advocate spécialisé dans les solutions serverless chez AWS), et adapté en français par Serge Moro, Architecte de Solutions Partenaires Senior chez AWS France, LinkedIn.