Nous avons ici quelques fonctions primitives génériques Pretty Good Privacy (PGP) présentées comme des appels d'API s'exécutant sur un serveur Node HTTPS:.
Ces fonctions ne sont pas spécifiques comme on pourrait l'utiliser pour dire, implémentent un plugin de messagerie électronique, mais sont plutôt destinées spécifiquement à une application d'enregistrement et d'autorisation de connexion d'utilisateur qui invoque les fonctions génériques pour prendre en charge son processus plus large. Les concepts et le code présentés ici sont facilement adaptables et sont partagés sur .
PGP est une implémentation d'un schéma de cryptographie à clé publique (PKC) généralement basé sur la méthode de chiffrement RSA .
PGP est généralement utilisé pour signer et chiffrer les messages électroniques qui sont ensuite vérifiés et déchiffrés par le destinataire. Une autre utilisation importante consiste à chiffrer des fichiers et des lecteurs pour protéger leur contenu. Notez que les caractéristiques de PKC/PGP rendent l'identité des participants à un tel échange ou transaction identifiable entre eux. En fait, notre cas d'utilisation est basé sur cet aspect du schéma.
Voici un article sur les schémas PKC qui donne de bonnes explications sur les concepts et les méthodes impliqués : //gzht888.com/public-key-cryptography-simply-explained-e932e3093046 .
PGP en tant que technique ou méthode de cryptage est disponible depuis un certain temps et a été codé ou programmé dans un bon nombre de langues et de plates-formes différentes.
L'implémentation JavaScript assez récente d'openPGPjs que nous utilisons est écrite en Nodejs en tant qu'API asynchrone et peut être trouvée dans ce référentiel : .
Shell de programme d'API Server.js
Nous fournissons une interface aux fonctions openPGPjs via un framework d'API Express Nodejs qui utilise les soumissions de formulaire POST de l'appelant.
Voici le code d'en-tête de notre programme API Nodejs server.js . Cette section de code montre les modules dont nous avons besoin pour l'inclusion.
Suite à ce code de titre, nous avons inséré ici un certain nombre de points d'entrée API pour les différentes fonctions que nous proposons. Une fois ces différentes fonctions API répertoriées, nous avons cette dernière brève section de code qui configure et exécute le serveur HTTPS : pour les fonctions API.
Notre API traite un certain nombre d'objets au cours de ses activités, et certains de ces objets sont stockés dans des tables dans une base de données et un est généré à partir du contenu d'une autre table de données.
Plus d'informations sur l'utilisation de la table de données plus tard, mais en attendant, ce bloc de code suivant est destiné à un module Node usersdb_conn.js qui nous connecte à la base de données mySQL de nos utilisateurs que nous utilisons généralement dans les fonctions API.
Fonctions PGP Server.js
Maintenant que nous avons décrit notre shell API général, nous pouvons examiner les fonctions qu'il présente à nos utilisateurs.
Fonction de générateur de clé
Pratiquement chaque fonction PGP emploie un ou plusieurs des trois objets importants dans ses déterminations et opérations. Le premier de ces objets est l'objet utilisateur qui, dans notre cas, est généré à partir de données sur l'utilisateur que nous extrayons d'une base de données avec l'adresse e-mail de l'utilisateur fournie via le message POST. Le contenu de cette base de données d'utilisateurs était auparavant rempli par une autre partie de notre processus d'inscription. Ici, dans la liste ci-dessous, nous pouvons voir la requête POST utilisée pour appeler la fonction de générateur de clé ainsi qu'une fonction pour obtenir le type de clé et la longueur en bits de la clé à partir d'un fichier de configuration et la fonction que nous utilisons pour extraire les valeurs de données utilisateur spécifiques. à partir de la table de la base de données.
Dans cette prochaine section de liste ci-dessous, nous voyons l'invocation de la fonction de génération de clé openPGP en utilisant les valeurs de données de prénom, nom, phrase de passe et e-mail que nous avons obtenues juste au-dessus. Une fois les clés générées dans cette version de démonstration, nous écrivons également chacune d'entre elles dans un fichier approprié.
Les deux fonctions ci-dessous vérifient l'existence des enregistrements de clé publique et privée dans les tables de données de clé publique et privée. Nous utilisons ces informations pour décider si nous insérons une nouvelle clé ou remplaçons/mettons à jour une clé déjà présente, comme indiqué dans la liste ci-dessous.
La fonction ci-dessous affiche une page de message de réussite de bannière salutaire au navigateur de l'utilisateur qui a envoyé la démo générer des clés API POST.
Ce code de page d'affichage de bannière de succès keygenWebpage que nous venons d'examiner ci-dessus est la dernière fonction utilisée dans la section POST du générateur de clé de l'API. Afin que ces fonctions individuelles accomplissent la tâche prévue de génération d'une paire de clés utilisateur, nous avons besoin d'une méthode pour mettre ces fonctions en file d'attente afin qu'elles s'exécutent dans un ordre propre à la tâche, chaque fonction fournissant à son tour sa contribution à la liste des tâches. . Ainsi, le code principal de l'appel d'API du générateur de clés dont nous avons discuté s'exécute dans le cadre de cette fonction de modèle "performAsyncFunctions" qui est un contrôleur de fonction asynchrone qui exécute chaque fonction de manière séquentielle, attendant que chaque fonction se termine avant de passer à la suivante.
Résultats du générateur de clés
Une fois que cet appel d'API de générateur de clé a été exécuté, nous aurons les trois objets généralement utilisés pour chiffrer ou déchiffrer et signer ou vérifier les messages texte à notre disposition.
Nous avons une page de menu HTML simple nommée sendPost.html illustrée ci-dessous ci-dessous pour démontrer ou exécuter les appels disponibles à partir de notre API.
Il s'agit de votre formulaire HTML de base qui envoie une requête POST à notre serveur API et les trois entrées pour créer une paire de clés sont implémentées avec ce code illustré ci-dessous.
Enfin, pour notre démo, nous affichons une page d'accueil signalant l'achèvement du processus de génération de clé. Cette complétion aboutit à trois objets de base pour l'utilisation du schéma PGP. L'un est celui de l'objet utilisateur avec ses attributs de prénom , nom , phrase de passe et adresse e -mail.
Notre générateur de clé a créé deux nouveaux objets supplémentaires pour notre usage, un objet clé publique et un objet clé privée .
Le journal de la console est utilisé pour afficher nos résultats et la progression de diverses fonctions, et ceci est un exemple de journal de la console de l'exécution de la démo du générateur de clé.
Quatre opérations sur nos trois objets
Il y a quatre opérations intéressantes que nous utilisons dans notre implémentation d'API. Ces opérations consistent à chiffrer un message , à signer un message , à déchiffrer un message et à vérifier un message .
Il est possible à la fois de chiffrer et de signer ou de déchiffrer et de vérifier un message, ce qui nous donne un tableau de six fonctions générales en dehors du générateur de clé.
Le chiffrement des messages utilise la clé publique de l'expéditeur tandis que le déchiffrement des messages utilise la clé privée et la phrase secrète du destinataire, de sorte que ces opérations complémentaires utilisent des clés complémentaires. La signature des messages utilise la clé privée et la phrase de passe du signataire tandis que la vérification utilise la clé publique d'une manière tout aussi complémentaire. Chiffrer un message ou déchiffrer un message sont les deux fonctions les plus courantes de PGP. Voyons comment ils sont implémentés dans notre API.
Chiffrer un message
Ce code ci-dessous est le début de notre appel API Encrypt. Comme on peut le voir, la première chose que nous faisons est d'obtenir l'adresse e-mail de l'expéditeur ou du crypteur à partir du message POST, puis d'obtenir le message en clair que nous souhaitons crypter avec la clé publique du crypteur, qui dans notre démo, est extraite d'un table de base de données basée sur l'e-mail que nous avons fourni dans notre appel API.
Une fois que nous avons le message en clair que nous voulons chiffrer avec la clé publique de l'expéditeur, nous pouvons continuer à chiffrer le message en utilisant une fonction openPGP comme indiqué ci-dessous. Pour notre démo, nous terminons l'appel API en écrivant le fichier chiffré sur le disque.
Toutes ces fonctions ci-dessus et utilisées dans notre appel d'API Encrypt sont exécutées dans l'ordre indiqué par la fonction asynchrone de fermeture "performEncryptAsyncFunctions" avec sa séquence en file d'attente de fonctions attendues répertoriées ci-dessus. La démo ne présente pas de message d'achèvement à notre utilisateur API pour cet appel, mais elle présente un fichier journal à notre terminal serveur, comme indiqué ci-dessous.
Décrypter un message
Une fois que nous avons un message texte crypté en notre possession, nous pouvons souhaiter lire son contenu en clair ou non crypté. Cela implique bien sûr le processus de déchiffrement qui est accompli par le code suivant. Nous commençons par analyser le message POST pour notre adresse e-mail d'utilisateur, suivi d'une fonction pour lire notre message crypté à partir d'un fichier.
Le déchiffrement dans notre cas d'utilisation nécessite à la fois une clé privée et une phrase de passe , et nous extrayons la phrase de passe de notre base de données d'utilisateurs comme indiqué ici.
Notre schéma PGP offre un niveau de protection supplémentaire par un processus connu sous le nom de « blindage » de la clé qui consiste à la crypter avec cette phrase secrète.
Outre ces deux fonctions précédentes, nous avons une fonction supplémentaire pour obtenir la clé privée de sa base de données.
Avec ces objets, nous pouvons déchiffrer le message et enregistrer le texte en clair dans un fichier en utilisant les deux premières fonctions de la liste ci-dessous.
Encore une fois, comme indiqué ci-dessus, nous utilisons notre construction "performAsyncFunctions" pour exécuter séquentiellement chaque fonction dans la liste d'attente. Comme cela a été fait avec l'appel d'API Encrypt, l'interaction fournie par cet appel d'API Decrypt consiste en un texte affiché sur le terminal de la console, comme indiqué dans cet exemple de journal ci-dessous.
Autres appels d'API
Outre les trois fonctions principales de génération de clé , de chiffrement de message et de déchiffrement de message, le code sert également quatre autres fonctions d'API qui sont signer et vérifier avec les appels d'API chiffrer et signer et déchiffrer et vérifier .
Le code et les résultats du journal du terminal pour ces API sont inclus dans le référentiel GitHub à l' Le code pour exécuter ce programme Node en tant que service sur Linux (Ubuntu20) est également inclus dans le référentiel GitHub.
Conclusion
Ce code est écrit plus comme une démo et un exemple d'API NodeJS que comme n'importe quel utilitaire prêt pour la production. J'espère que cela servira bien cet objectif car vous voyez que je l'ai écrit comme mon propre exemple de démonstration. Il devrait être facilement adaptable à vos propres fins. Les commentaires ou suggestions sont les bienvenus.
Également publié