You are on page 1of 17

APRENDIENDO SEGURIDAD INFORMÁTICA: APSI

(LEARNING INFORMATION SECURITY: LEIS)

INTRODUCCIÓN A PKI (PUBLIC KEY INFRASTRUCTURE) Y CRIPTOGRAFÍA

NOCIONES DE SEGURIDAD INFORMÁTICA

v0.1 – Febrero 17 de 2014

Por Sebastián Villa

Ingeniero Electrónico (Electronics Engineer)

jastazv.co – ​jastazv@gmail.com

Licencia:

Creative Commons Attribution 4.0 International

Qué objetivo tiene este documento:

Tener todos los conceptos implicados lo suficientemente claros como para explicarlos y poder
graficarlos. Por ejemplo explicar por qué es necesario codificar en ASN.1 y en BER o DER, en lo
posible con ejemplos para el mejor entendimiento y memorización, para la posteridad.

Listado de temas:

1. PKI: Conceptos básicos.


2. Creación de una autoridad certificadora propia.

Se creará la entidad certificadora o autoridad certificadora (CA) ficticia ​SYTECSA Security Labs CA
con el objetivo de emitir estos certificados para realizar pruebas.

A grandes rasgos el proceso es como sigue:

1. Creación de llave privada para certificado raíz.


2. Creación/Firma de certificado raíz (root CA) auto-firmado (self-signed).
3. Creación de llave privada para certificado intermedio (intermediate CA).
4. Creación de CSR de certificado intermedio para firma por parte de certificado raíz (root
CA).
5. Creación/Firma de certificado intermedio (intermediate CA) por certificado raíz.
6. Creación de llave privada para certificado emitido (issued certificate) para
cliente/empresa.
7. Creación de CSR de certificado emitido para firma por parte de certificado intermedio
(intermediate CA).
8. Creación/Firma de certificado emitido (issued certificate) por certificado intermedio.

Se utilizarán entonces tres (3) tipos de certificados:

● Certificado raíz.
● Certificado intermedio.
● Certificado emitido.

Estos tres (3) certificados permiten explicar el concepto de “Chain of Trust” o cadena de confianza
o cadena de certificados:

Nota: ​Para la ejecución de los comandos referidos en este documento es necesario tener instalado
OpenSSL​ y agregado al ​PATH​ de Windows. Véase documento “​Instalación y configuración de
OpenSSL.pdf​”.

Es de aclarar que el único certificado auto-firmado (self-signed) es el certificado raíz, es decir, que
sus campos ​IssuedTo​ and ​IssuedBy​ son iguales y corresponden a ​SYTECSA Security Labs CA.​

Este proceso es el mismo que se realizaría para una entidad certificadora real como Verisign,
Thawte o Digicert, por lo cual es necesario dominar y entender este procedimiento.

¿Por qué comprar un certificado a Verisign, Thawte o Digicert? ¿No me sirve SYTECSA Security
Labs CA?

En términos generales para que la validación de un archivo firmado por un cliente/empresa a


partir de un certificado emitido por SYTECSA Security Labs CA y utilizando su llave privada, sea
exitosa, es necesario que en el lugar de verificación estén instalados o “sean conocidos” todos los
certificados de la cadena de confianza de SYTECSA Security Labs CA, es decir, el certificado raíz y el
certificado intermedio, esto con el objetivo de que el elemento validador pueda verificar que el
certificado emitido es verdadero y el archivo firmado por el cliente/empresa sea considerado
como válido.

Dependiendo de los usos de la firma digital, y más en términos generales, de un certificado digital
y del ámbito en el que se requiera que sea reconocido y utilizado, es que se hace necesario
comprar o no un certificado de una entidad como Verisign, Thawte o Digicert.

Nota: E​ xisten muchas otras autoridades de certificación, CAs, véase


http://www.sos.ca.gov/digsig/​,
http://www.sslshopper.com/certificate-authority-reviews.html​, para conocer el listado de
las más importantes.

Por ejemplo para la validación de un servidor o sitio web es necesario que el navegador web o
browser conozca la cadena de confianza para poder verificar la validez del certificado del servidor.

Para esto estas compañías como Verisign, Thawte o Digicert han invertido enormes cantidades de
dinero para que los navegadores, sistemas operativos y diversas aplicaciones, incluyan sus
certificados raíz e intermedios (pueden tener diferentes certificados intermedios dependiendo del
uso) y permitan que todos los usuarios puedan validar los certificados emitidos para los servidores
a los que se conectan a través de sus navegadores. Por ejemplo, en este enlace se pueden ver los
certificados de CA que incluye el Mozilla Firefox:
https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/included/​. Notar
que sólo se incluyen los certificados raíces, ¿por qué no se incluyen lo intermedios? En la
validación de la cadena de certificados…. El servidor web debe tener los certificados intermedios
instalados y en el momento de la comunicación (más específicamente el handshaking de
OpenSSL), se envía la lista de certificados (certificate bundle) para que el cliente pueda realizar la
validación del certificado del servidor verificando que la cadena de validación sea válida para
alguno de los certificados raíz en el navegador. Los certificados que incluyen el Mozilla Firefox o
Windows por defecto se conocen como Trust Anchors (traducido ​anclas de confianza​, véase
http://en.wikipedia.org/wiki/Trust_anchor​),​ son los puntos finales en la cadenas de confianza y en
donde termina la validación. Estos son los certificados raíz de CA que vienen preinstalados con los
navegadores y con el Sistema Operativo.

Mozilla Firefox tiene su propia lista en todas las plataformas. Internet Explorer y Google Chrome
utilizan el almacén de certificados de Windows.

Los certificados pueden tener diferentes usos, por ejemplo, véase listado:

http://wiki.aaf.edu.au/tech-info/certificate-management

Nota:​ Las longitudes de llave de los diferentes certificados pueden ser diferentes. Por ejemplo, la
llave privada del certificado raíz puede ser de 4096, la del certificado intermedio puede ser de
2048 y la del certificado del cliente/empresa puede ser de 1024. También pueden ser todos de
1024, 2048 o 4096, sin embargo, se recomienda no usar longitudes de 1024 ya que la seguridad
para esta longitud ya se ha visto comprometida (ver
https://www.globalsign.eu/ssl-information-center/1024-bit-public-and-private-keys.html​. Para
diferentes recomendaciones en la selección de la longitud de la llave privada véase
http://www.keylength.com/en/4/​).
Un esquema práctico sería usar llaves de 2048 tanto para el certificado intermedio y el certificado
del cliente/empresa y llave de 4096 para el certificado raíz.

La llave privada reside en el servidor donde se generó el CSR.

En el caso de una red interna no es necesario utilizar o comprar un certificado de una CA


comercial, por ejemplo en el caso de una VPN.

Normalmente le certificado intermedio y el certificado emitido para el servidor o el dominio se


concatenan en uno sólo creando un ​bundle de certificados. (Un ​bundle de certificados es
típicamente un archivo PEM con varios certificados incluidos en él).

Estos 4 principios se cumplen al utilizar SSL v3.0/TLS v1.0 o superiores:

● Autenticación del cliente: verifica la identidad del cliente a partir del intercambio y
validación de certificados.
● Autenticación del servidor: verifica la identidad del servidor a partir del intercambio y
validación de certificados.
● Privacidad en la comunicación: encripta en un canal seguro la información que se
intercambia entre clientes y servidores.
● Integridad en la comunicación: garantiza la integridad del contenido de los mensajes que
son intercambiados entre clientes y servidores al garantizar que los mensajes no han sido
alterados durante la transmisión.

El certificado intermedio normalmente se instala en el servidor y en el momento de la negociación


SSL, el servidor envía la cadena de confianza (certificado emitido más certificado intermedio) para
que el cliente pueda verificar toda la cadena de confianza. Si el certificado intermedio el cliente no
podrá verificar la cadena de confianza.

Algoritmo RSA

¿Qué es? Historia, descripción breve.

Para hacerse una idea del tiempo que puede tomar factorizar un entero de 2048 bits en factores
de dos números primos véase ​http://www.digicert.com/TimeTravel/math.htm​.
Recomendaciones de seguridad

Se recomienda utilizar una llave para diferente para la encripción y para la firma, sin embargo, con
el objetivo de simplificar el ejemplo, utilizaremos la misma llave para encripción y firmado.

¿Matemáticamente cuál es la diferencia entre firmar y encriptar en RSA?

En el algoritmo RSA son operaciones matemáticas diferentes e inversas, firmar y encriptar.

Para entender, se debe revisar el concepto del algoritmo RSA. Véase para claridad:

http://tools.ietf.org/html/rfc3447#section-5.1

En el algoritmo RSA, la llave de encripción es pública y la llave de des-encripción es privada.

El algoritmo RSA comprende 3 pasos:

1. Generación de llaves, llave privada y llave pública.


2. Encripción.
3. Des-encripción.

La llave pública es conocida por todos y se utiliza para encriptar. Los mensajes encriptados con la
llave pública sólo pueden ser des-encriptados por la llave privada en una cantidad de tiempo
razonable, más adelante se entenderá esto del tiempo.

Generación de llaves

1. Seleccionar dos números primeros p y q . Por propósitos de seguridad p y q deben ser


seleccionados aleatoriamente y con longitud en bits similar.
2. Calcular n = pq , siendo n el módulo de la llave privada y la llave pública. La longitud del
módulo n en bits se conoce como la longitud de la llave o ​key-length​.
3. Calcular φ (n) = φ (p) φ(q) = (p − 1)(q − 1) . Se calcula la función φ (n) que la cantidad
de coprimos menores o iguales a n . Se dice que un número k es coprimo a n si el mayor
divisor común (mdc) entre ellos es 1 , por ejemplo 2 es coprimo de 9 pues su mdc es 1 ;
por ejemplo, se tiene que φ(9) = 6 , porque sus coprimos son {1, 2, 4, 5, 7, 8}. En el caso
de un número primo x es φ(x) = x − 1 , debido a que todos los números menores a x
son coprimos de x . Por ejemplo φ(7) = 6 ya que sus coprimos son {1, 2, 3, 4, 5, 6} . 7 es
un número primo, por ende se puede ver que φ(7) = 7 – 1 = 6.
4. Seleccionar un entero ​e , 1 <= e <= φ(n) ​tal que e sea coprimo de φ(n) . e s​ e conoce
como el exponente público. Normalmente e t​ iene el valor de 65537 (en HEX 0x10001).
5. Calcular ​d​ como d .e = 1 (mod φ(n) ) . d ​se conoce como el exponente privado.

La llave pública se compone del módulo n y el exponente público e y la llave privada se compone
de módulo n y el exponente privado d . El exponente público e también se conoce como
exponente de encripción y el exponente privado d también se conoce como exponente de
des-encripción.

La llave privada se utiliza para des-encriptar y firmar y la llave pública se utiliza para encriptar y
verificar firmas.

Encripción

RSA se utiliza para encriptar mensajes de tamaño limitado. Para una longitud de llave de 2048-bits
es posible encriptar datos de hasta 245 bytes de tamaño. Para encriptar mayor cantidad de
información se debe recurrir a algoritmos como AES pues con una llave de 128-bits permite
encriptar datos de hasta 250 millones de Terabytes.

Teniendo acceso a la información de la llave pública ( n y e ), y con el objetivo de encriptar un


mensaje ​M s​ e sigue el siguiente procedimiento:

1. Llevar ​M​ a un entero ​m ​ tal que 0 ≤ m ≤ n . Normalmente se encripta el hash o digest del
mensaje M para procesos de firma ya que para realizar encripciones de mayor información
es recomendable utilizar otros algoritmos como AES. Un digest o hash muy empleado es
SHA-1 (véase ​http://en.wikipedia.org/wiki/SHA-1​). Para una llave de 2048-bits es decir 256
bytes, según el estándar PKCS#1 v1.5 se deben destinar 11 bytes de padding por lo que
quedan 256-11 = 245 bytes disponibles para información, como se mencionó al inicio de
esta sección (para referencias sobre el padding según estándar PKCS#1 v1.5 véase
http://tools.ietf.org/html/rfc2313​). El padding son bytes que se agregan según un patrón o
estándar de tal forma que la encripción RSA sea más segura y no sea vulnerable a ataques
tipo ​plaintext​ (véase
http://en.wikipedia.org/wiki/RSA_(cryptosystem)#Padding_schemes)​.
En el caso de SHA-1 el digest tiene 20 bytes (160-bits) de longitud. Estos 20 bytes más los 11 bytes
de padding dan 33 bytes que termina siendo un número menor a ​n​ cuya longitud es de
256 bytes.
2. Después de tener ​m se encriptará teniendo como resultado ​c​, el mensaje encriptado, al
realizar la siguiente operación:
c = me (mod n )
​ uede ser enviado o transmitido para su posterior
Después de realizar estos dos pasos, c p
des-encripción.

Des-encripción

Para obtener el contenido de m a partir de c , teniendo que el exponente privado es d , se realiza


la siguiente operación:

m = cd (mod n )

El mensaje original M s​ e puede obtener al reversar el padding de m .

Firma

s = md (mod n )

Verificación

m = se (mod n )

A continuación se provee un ejemplo numérico de cómo sería todo el proceso del algoritmo RSA
para encriptar, des-encriptar, firmar y verificar tendiendo que el mensaje es la letra equis
mayúscula “​X​”:

M = {′X ′}

Este texto consta de 1 caracteres, es decir, 1 byte. Representada en hexadecimal sería: (Para
realizar conversión de ASCII a hexadecimal véase ​http://www.asciitohex.com/​)

m = 0x58

Que en decimal sería:

m = 88
(Para realizar conversión de hexadecimal a decimal utilizar:
http://easycalculation.com/hex-converter.php​).

Este número es el mensaje que encriptará y firmará. Con el objetivo de simplificar y trabajar con
números pequeños no se realizará padding del mensaje según PKCS#1v1.5. (Para ejemplo con
padding véase ​http://www.di-mgt.com.au/rsa_alg.html#signpkcs1​)​.

Como anexo de los ejemplos se provee el programa en lenguaje Java


RSAEncryptionCalculator.java​ que muestra el ejemplo y los cálculos realizados.

Nota: ​Para la ejecución del programa es necesario tener ​JDK instalado con variable de entorno
JAVA_HOME apuntando a directorio ​de JDK y directorio ​/bin de ​JDK incluido en el ​PATH.​
Para compilar el programa situarse en el directorio del código y digitar

javac RSAEncruptionCalculator.java

Para ejecutar el programa digitar:

java RSAEncryptionCalculator

Generación de llaves

1. Seleccionar dos números primos diferentes. Seleccionaremos p = 103 y q = 79 . Se


pueden seleccionar los que se deseen, por ejemplo, basarse en este listado de los
primeros 1000 números primos: ​http://primes.utm.edu/lists/small/1000.txt​.
2. Calcular n = pq , por lo tanto n = 103 * 79 = 8137 .
3. Calcular φ(n) = (p − 1)(q − 1) , por lo tanto​ φ (n) = (102) (78) = 7956 .
4. Seleccionar un número e que sea coprimo y menor a φ (n) . Para seleccionarlo basta con
encontrar un número que no sea divisor exacto de φ (n) ; para mayor facilidad de
encontrar e , seleccionar un número primo, por ejemplo e = 151 .
5. Calcular d ​según
d .e = 1 (mod φ (n)) d . 151 = 1 (mod 7956 )

Esta expresión se calcula según el inverso modular. Para realizar el cálculo del inverso modular
existen diferentes implementaciones en diferentes lenguajes, como se puede ver acá:

Por ejemplo, empleando la implementación en lenguaje C,

#include​ ​<stdio.h>

int​ ​mul_inv​(​int​ a, ​int​ b)


{
int​ b0 = b, t, q;
int​ x0 = 0, x1 = 1;
if​ (b == 1) ​return​ 1;
while​ (a > 1) {
q = a / b;
t = b, b = a % b, a = t;
t = x0, x0 = x1 - q * x0, x1 = t;
}
if​ (x1 < 0) x1 += b0;
return​ x1;
}

int​ ​main​(​void​) {
printf​(​"%d\n"​, mul_inv(151, 7956));
return​ 0;
}

Al ejecutarse el programa nos imprimirá en pantalla:

2371

Nota: para encontrar implementaciones del cálculo de inverso multiplicativo modular (​Module
Multiplicative Inverse​) veáse ​http://rosettacode.org/wiki/Modular_inverse​.
También es posible encontrar múltiples implementaciones en lenguaje C++ en
http://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse
/​.

Por lo tanto,

d = 2371

6. La llave pública sería {n = 8137, e = 151} y la llave privada sería {n = 8137, d = 2371} .

Encripción

Después de tener generadas nuestras llaves pública y privada y teniendo definido nuestro mensaje
m , procederemos a hacer la encripción.

La función de encripción es:

c = m151 (mod 8137 )

c = 88151 (mod 8137 )


El resultado de esta operación es:

c = 5936

Des-encripción

A partir de c ​podemos recuperar m ​a través de la función de des-encripción:

m = c2371 (mod 8137 )

Entonces,

m = 59362371 (mod 8137)

m = 88

Como se puede ver, se ha obtenido el valor de m que se esperaba.

Firma

La función de firma es:

s = m2371 (mod 8137 )

s = 882371 (mod 8137 )

El resultado de esta operación es:

s = 1585

Verificación

A partir de s ​podemos recuperar y validar m ​a través de la función de verificar:

m = s151 (mod 8137 )


Entonces,

m = 15852371 (mod 8137)

m = 88

Como se puede ver, se ha obtenido el valor de m que se esperaba.

Algoritmo RSA utilizando CRT (Chinese Remainder Theorem)

Dado que el exponente privado d tiene un orden mucho mayor al exponente público e , los
procesos de des-encripción y firma son mucho más costosos computacionalmente, ya que d ​es un
número de un orden cercano a la longitud de la llave.

El Teorema del Residuo Chino se utiliza para mejorar el rendimiento y aumentar la velocidad de
cálculo en el algoritmo RSA en la des-encripción y en la firma. Utilizando CRT se puede mejorar la
velocidad de cálculo de la exponenciación modular hasta 4 veces.

Des-encripción utilizando CRT

A partir de la función de des-encripción convencional

m = cd (mod n )

Para calcular m dado c , con p > q , se pre-calculan los siguientes valores:

dp = e−1 (mod (p − 1) )

dq = e−1 (mod (q − 1) )

q inv = q −1 (mod p )

para la obtener m se calcula:

m1 = cdp (mod p ) m2 = cdq (mod q ) h = q inv . (m1 − m2 ) (mod p ) m = m2 + h .q

Utilizando los valores del ejemplo anterior tendríamos:

dp = 151−1 (mod (102) )


dq = 151−1 (mod (78) )

q inv = 79−1 (mod 103 )

dp = 25

dq = 31

q inv = 30

m1 = 593625 (mod 103 ) m2 = 593631 (mod 79 )

m1 = 88m2 = 9

h = 30 . 79 (mod 103 ) h = 1

m = 9 + 1 .79

m = 88

Como se puede ver, se ha obtenido el valor de m que se esperaba.

Firma utilizando CRT

A partir de la función de firma convencional

s = md (mod n )

Para calcular s dado m , con p > q , se pre-calculan los siguientes valores:

dp = e−1 (mod (p − 1) )

dq = e−1 (mod (q − 1) )

q inv = q −1 (mod p )

para la obtener s se calcula:

s1 = mdp (mod p ) s2 = mdq (mod q ) h = q inv . (s1 − s2 ) (mod p ) s = s2 + h .q


Utilizando los valores de los ejemplos anteriores tendríamos (este es un ejemplo de pre-cálculo,
sólo fue necesario calcularlos en la des-encripción):

dp = 25

dq = 31

q inv = 30

s1 = 8825 (mod 103 ) s2 = 8831 (mod 79 )

s1 = 40s2 = 5

h = 30 . 35 (mod 103 ) h = 20

s = 5 + 20 .79

s = 1585

Como se puede ver, se ha obtenido el valor de s que se esperaba.

¿Por qué son necesarias las estructuras de ASN.1?

Es necesario almacenar la información en una jerarquía o según un estándar.


¿ASN.1 vs BER vs DER? ¿En qué se diferencian?

Para mayor entendimiento de cómo funciona la validación de la cadena de certificados de


confianza véase ​http://www.oasis-pki.org/pdfs/Understanding_Path_construction-DS2.pdf y
http://en.wikipedia.org/wiki/Certification_path_validation_algorithm​.

Para una muy buena y completa explicación de ASN.1, BER y DER véase
http://luca.ntop.org/Teaching/Appunti/asn1.html​.

Muy buen ejemplo: ​http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

Véase ​http://en.wikipedia.org/wiki/Basic_Encoding_Rules#BER_encoding

ASN.1 se utiliza para definir la estructura de la información de manera abstracta por ende
independiente y genérica. La manera de representar/definir/codificar esa información se través de
reglas de codificación como BER o DER. ASN.1 se utiliza para definir protocolos. Un protocolo es la
estructura de un concepto o estándar.

La codificación en base64 se utiliza para llevar toda esta información binaria a caracteres
imprimibles. Se utiliza bas64 para transferir la información de modo texto ya que en algunos
ambientes la información binaria puede ser interpretada como sentencias de control, por esto se
codifica la información en modo texto (ASCII). Esto permite que información binaria sea más fácil
transferible en medios como HTTP e Email.

Para ver referencia de nombres OID véase


http://www.antillia.com/sol9.2.0/classes/OIDNames.html​.

La primera versión de PCKS#7 fue 1.5 de 1998, véase: ​https://www.ietf.org/rfc/rfc2315.txt

Para ver toda la evolución que ha tenido el estándar CMS (​Cryptographic Message Syntax​) véase
http://tools.ietf.org/html/rfc5652#section-1.1​.

Super interesante para realizar la firma en PKCS#7 con OpenSSL:


http://qistoph.blogspot.nl/2013/04/pkcs7-and-openssl.html

http://qistoph.blogspot.com/2012/01/manual-verify-pkcs7-signed-data-with.html

Y en Java:

http://stackoverflow.com/questions/10703416/sign-data-using-pkcs-7-in-java

Cómo se relaciona S/MIME con CMS y PKCS#7?

S/MIME es un protocolo para email/correo seguro. Utiliza a CMS para la parte criptográfica
(encripción, firmado) y agrega unas reglas y definiciones en el uso de CMS en el ámbito de los
correos.

MIME: Multiporpuse Internet and Media Extensiones

La implementación de base de datos de certificados provee los mecanismos para encontrar los
certificados en el path de certificación según su RDN y serialNumber.

Es posible utilizar y firmar CSRs (​Certificate Signing Request,​ véase


http://www.sslshopper.com/what-is-a-csr-certificate-signing-request.html​) directamente con el
certificado raíz sin embargo se recomienda utilizar certificados intermedios por las siguientes
razones:

● Si la llave privada del certificado intermedio es comprometida, se puede realizar una


revocación del certificado a través de una CRL sin necesidad de cambiar el certificado raíz
o su llave y se puede expedir un nuevo certificado intermedio.
● Se busca crear una cadena de confianza en donde el certificado raíz esté lo menos
expuesto posible, que esté “offline”, es decir, oculto. Esto comúnmente se denomina
“​Certificate Chain​” o “​Chain of Trust​”.
● Por propiedad de transitividad, si el certificado intermedio es firmado por el certificado
raíz, todos los certificados firmados por el certificado intermedio son firmados por el
certificado raíz.

Por esa razón, se muestra cómo generar tanto el certificado raíz como el certificado intermedio.
Para la validación de la firma digital en el equipo es necesario que se encuentren ambos
certificados, tanto el certificado raíz como el certificado intermedio, en el “Almacén de
certificados de Windows”. Nótese que no es necesario realizar la importación del certificado
emitido al cliente/empresa.

3. ASDFADSF
4. Asdfasdfasd
5.

Al extraer los parámetros de RSA a través de OpenSSL, qué significan?

version Version,

modulus INTEGER, n

publicExponent INTEGER, e

privateExponent INTEGER, d

prime1 INTEGER, p

prime2 INTEGER, q

exponent1 INTEGER, d mod (p-1)

exponent2 INTEGER, d mod (q-1)

coefficient INTEGER, (inverse of q) mod p

Para ver las equivalencias véase también ​http://www.vidarholen.net/contents/blog/?p=24​.

Los últimos tres valores se pueden entender según el Teorema del Residuo Chino:

http://en.wikipedia.org/wiki/RSA_(algorithm)#Using_the_Chinese_remainder_algorithm

Para la instalación de ​OpenSSL s​ e definió la variable de entorno ​RANDFILE​ con valor


C:\sytecsa\firma_digital\openssl\randfile.rnd​ esto para evitar mensajes de error en la generación
de números aleatorios por parte de ​OpenSSL​.

¿Qué es PEM?
Privacy Enhanced Mail es un estándar que no tuvo mucho uso y hoy se considera inactivo o
muerto. Algunos remanentes de este estándar para privacidad en correo quedan como lo son los
encabezados de los diferentes formatos de archivo en PKI, sin embargo estos formatos no están
estandarizados y son básicamente convenciones históricas.

Referencias

● Para algoritmo RSA utilizando el Teorema del Residuo Chino véase


http://www.di-mgt.com.au/crt_rsa.html​.