Aquí tenemos algunas funciones primitivas genéricas de Pretty Good Privacy (PGP) presentadas como llamadas API que se ejecutan en un servidor Node HTTPS:.
Estas funciones no son específicas, ya que podrían usarse para decir, implementar un complemento de mensajería de correo electrónico, sino que están destinadas específicamente para una aplicación de autorización de registro e inicio de sesión de usuario que invoca las funciones genéricas para respaldar su proceso más amplio. Los conceptos y el código que se muestran aquí son fácilmente adaptables y se comparten en .
PGP es una implementación de un esquema de criptografía de clave pública (PKC) generalmente basado en el método de cifrado RSA .
PGP generalmente se emplea para firmar y cifrar mensajes de correo electrónico que luego son verificados y descifrados por el destinatario. Otro gran uso es cifrar archivos y unidades para proteger su contenido. Tenga en cuenta que las características de PKC/PGP hacen que la identidad de los participantes en dicho intercambio o transacción sea identificable entre sí. De hecho, nuestro caso de uso se basa en este aspecto del esquema.
Aquí hay un artículo sobre esquemas PKC que brinda algunas buenas explicaciones de los conceptos y métodos involucrados: //gzht888.com/public-key-cryptography-simply-explained-e932e3093046 .
PGP como técnica o método de encriptación está disponible desde hace algún tiempo y ha sido codificado o programado en un buen número de lenguajes y plataformas diferentes.
La implementación bastante reciente de JavaScript de openPGPjs que usamos está escrita en Nodejs como una API asíncrona y se puede encontrar en este repositorio: .
Shell del programa API Server.js
Proporcionamos una interfaz para las funciones de openPGPjs a través de un marco API de Express Nodejs que utiliza los envíos de formularios POST de la persona que llama.
A continuación se muestra el código de encabezado en nuestro programa API server.js de Nodejs . Esta sección de código muestra los módulos que requerimos para su inclusión.
Siguiendo este código de encabezado, hemos insertado una serie de puntos de entrada de API aquí para las diversas funciones que ofrecemos. Después de enumerar estas diversas funciones de API, tenemos esta breve sección final de código que configura y ejecuta el servidor HTTPS: para las funciones de API.
Nuestra API trata con una serie de objetos en el curso de sus actividades, y algunos de esos objetos se almacenan en tablas en una base de datos y uno se genera a partir del contenido de otra tabla de datos.
Más sobre el uso de la tabla de datos más adelante, pero mientras tanto, este siguiente bloque de código es para un módulo de nodo usersdb_conn.js que nos conecta a la base de datos mySQL de nuestros usuarios que tenemos en uso general dentro de las funciones de la API.
Funciones PGP de Server.js
Ahora que hemos descrito nuestro shell API general, podemos ver las funciones que presenta a nuestros usuarios.
Función de generador de claves
Prácticamente todas las funciones de PGP emplean uno o más de tres objetos importantes en sus determinaciones y operaciones. El primero de estos objetos es el objeto de usuario que, en nuestro caso, se genera a partir de datos sobre el usuario que extraemos de una base de datos con la dirección de correo electrónico del usuario proporcionada a través del mensaje POST. El contenido de esta base de datos de usuarios fue rellenado previamente por otra parte de nuestro proceso de registro. Aquí, en la lista a continuación, podemos ver la solicitud POST utilizada para invocar la función de generador de claves, así como una función para obtener el tipo de clave y la longitud de bits de clave de un archivo de configuración y la función que usamos para extraer los valores de datos de usuario específicos. de la tabla de la base de datos.
En la siguiente sección de listado a continuación, vemos la invocación de la función de generación de claves openPGP utilizando los valores de datos de nombre, apellido, frase de contraseña y correo electrónico que obtuvimos justo arriba. Una vez que se generan las claves en esta versión de demostración, también escribimos cada una de ellas en un archivo apropiado.
Las dos funciones a continuación verifican la existencia de registros de claves públicas y privadas en las tablas de datos de claves públicas y privadas. Usamos esta información para decidir si estamos insertando una nueva clave o reemplazando/actualizando una clave ya presente como se muestra en la lista debajo de esta.
La siguiente función a continuación muestra una página de mensaje de éxito de banner saludable para el navegador del usuario que envió la demostración para generar claves API POST.
Este código de página de visualización de banner de éxito de keygenWebpage que acabamos de examinar es la última función utilizada en la sección POST del generador de claves de la API. Para que estas funciones individuales realicen la tarea prevista de generar un par de claves de usuario, necesitamos un método para poner en cola estas funciones para que se ejecuten en un orden adecuado a la tarea con cada función, a su vez, proporcionando su contribución a la lista de tareas. . Entonces, el código principal para la llamada a la API del generador de claves que hemos estado discutiendo se ejecuta como parte de esta función de modelo "performAsyncFunctions", que es un controlador de función asincrónica que ejecuta cada función secuencialmente, esperando que se complete cada función antes de pasar a la siguiente.
Resultados del generador de claves
Una vez que se haya ejecutado esta llamada a la API del generador de claves, tendremos los tres objetos que generalmente se usan para cifrar o descifrar y firmar o verificar los mensajes de texto disponibles para nuestro uso.
Tenemos una página de menú HTML simple llamada sendPost.html que se muestra aquí debajo de la configuración para demostrar o ejecutar las llamadas disponibles desde nuestra API.
Este es su formulario HTML básico que envía una solicitud POST a nuestro servidor API y las tres entradas para crear un par de claves se implementan con este código que se muestra a continuación.
Finalmente, para nuestra demostración, mostramos una página de banner que indica la finalización del proceso de generación de claves. Esta finalización da como resultado tres objetos centrales para el uso del esquema PGP. Uno es el del objeto de usuario con sus atributos de nombre, apellido , frase de contraseña y dirección de correo electrónico .
Nuestro generador de claves ha creado dos nuevos objetos adicionales para nuestro uso, un objeto de clave pública y un objeto de clave privada .
El registro de la consola se usa para mostrar nuestros resultados y el progreso de varias funciones, y este es un registro de consola de ejemplo de la ejecución de la demostración del generador de claves.
Cuatro operaciones en nuestros tres objetos
Hay cuatro operaciones de interés que utilizamos en nuestra implementación de API. Estas operaciones son para cifrar un mensaje , firmar un mensaje , descifrar un mensaje y verificar un mensaje .
Es posible cifrar y firmar o descifrar y verificar un mensaje, por lo que esto nos brinda una tabla de seis funciones generales además del generador de claves.
El cifrado de mensajes usa la clave pública del remitente, mientras que el descifrado de mensajes usa la clave privada y la frase de contraseña del destinatario, por lo que estas operaciones complementarias usan claves complementarias. La firma de mensajes usa la clave privada y la frase de contraseña del firmante, mientras que la verificación usa la clave pública de manera complementaria similar. Cifrar un mensaje o descifrar un mensaje son las dos funciones de PGP más comunes. Veamos cómo se implementan en nuestra API.
Cifrar un mensaje
Este código que se muestra a continuación es el comienzo de nuestra llamada a la API de Encrypt. Como puede verse, lo primero que hacemos es obtener la dirección de correo electrónico del remitente o del cifrador del mensaje POST, seguido de obtener el mensaje de texto sin formato que deseamos cifrar junto con la clave pública del cifrador, que en nuestra demostración se extrae de un tabla de base de datos basada en el correo electrónico que proporcionamos en nuestra llamada API.
Una vez que tenemos el mensaje de texto sin formato que queremos cifrar junto con la clave pública del remitente, podemos continuar cifrando el mensaje usando una función openPGP como se muestra a continuación. Para nuestra demostración, finalizamos la llamada a la API escribiendo el archivo cifrado en el disco.
Todas estas funciones anteriores y utilizadas en nuestra llamada API de Encrypt se ejecutan en el orden indicado por la función asincrónica de cierre "performEncryptAsyncFunctions" con su secuencia en cola de funciones esperadas enumeradas anteriormente. La demostración no presenta un mensaje de finalización a nuestro usuario de API para esta llamada, pero presenta un archivo de registro a nuestro terminal de servidor como se muestra a continuación.
Descifrar un mensaje
Una vez que tenemos un mensaje de texto encriptado en nuestro poder, es posible que deseemos leer su texto sin formato o su contenido sin encriptar. Esto, por supuesto, implica el proceso de descifrado que se lleva a cabo mediante el siguiente código. Comenzamos analizando el mensaje POST para la dirección de correo electrónico de nuestro usuario seguido de una función para leer nuestro mensaje cifrado desde un archivo.
El descifrado en nuestro caso de uso requiere una clave privada y una frase de contraseña , y extraemos la frase de contraseña de nuestra base de datos de usuarios como se muestra aquí.
Nuestro esquema PGP proporciona un nivel adicional de protección mediante un proceso conocido como " protección " de la clave, que implica cifrarla con esta frase de contraseña.
Además de estas dos funciones anteriores, tenemos una función adicional para obtener la clave privada de su base de datos.
Con estos objetos, podemos descifrar el mensaje y guardar el texto sin formato en un archivo usando las dos primeras funciones en la lista a continuación.
Una vez más, como se muestra arriba, usamos nuestra construcción "performAsyncFunctions" para realizar secuencialmente cada función en la lista de espera. Tal como se hizo con la llamada a la API de Encrypt, la interacción proporcionada por esta llamada a la API de Decrypt consiste en el texto que se muestra en el terminal de la consola, como se muestra en este registro de ejemplo a continuación.
Otras llamadas a la API
Además de las tres funciones principales de generación de claves , cifrado de mensajes y descifrado de mensajes, el código también sirve para otras cuatro funciones de API que son firmar y verificar junto con las llamadas API de encriptar y firmar y desencriptar y verificar .
El código y los resultados del registro del terminal para estas API se incluyen en el repositorio de GitHub en El código para ejecutar este programa Node como un servicio en Linux (Ubuntu20) también se incluye en el repositorio de GitHub.
Conclusión
Este código está escrito más como una demostración y un ejemplo de API de NodeJS que como una utilidad lista para producción. Con suerte, servirá bien para ese propósito, ya que lo escribí como mi propio ejemplo de demostración. Debe ser fácilmente adaptable a sus propios fines. Comentarios o sugerencias son bienvenidos.
También publicado