Una introducción práctica a la infraestructura web de clave pública y los contratos inteligentes con la excusa de mejorar la consulta del estado de revocación de un certificado digital.
Contenido:
- La introducción
- El cifrado de la información
- La clave de sesión
- La firma digital
- Los certificados digitales
- Las autoridades de certificación
- El poder de los navegadores
- El poder de la autoridades de certificación
- La infraestructura de clave pública
- El problema de la infraestructura de clave pública
- El estado de revocación un certificado
- La listas de revocación de certificados
- La consulta de revocación de un certificado en línea
- La cadena de bloques y los contratos inteligentes
- La lista de certificados revocados descentralizada
- Los nodos y los clientes de Ethereum
- La cartera
- El contrato inteligente
- El entorno de desarrollo
- La seguridad de un contrato inteligente
- La extensión para el certificado
- La visualización de la extensión DCRL
- La emisión del certificado con soporte DCRL
- La herramienta para consultar la DCRL
- La herramienta para revocar un certificado DCRL
- El certificado completo
- Las conclusiones
Parte I
La introducción
Cuando accedemos a un sitio web a través de nuestro navegador, esperamos que la información que intercambiamos con ese sitio sea confidencial e integra. No queremos que terceros vean nuestras credenciales de acceso al banco o que alguien sepa cuántas criptomonedas estamos comprando en nuestro exchange favorito[1]Mejor sería usar un exchange descentralizado.. Por eso añadimos la “s” de seguro al “http” cada vez que introducimos una dirección web en la barra de direcciones de nuestro navegador[2]HTTP (Hypertext Transfer Protocol) son unas reglas que permiten realizar peticiones de documentos y recursos a otro ordenador mediante TCP. Las respuestas pueden contener enlaces a otros … Continue reading. De hecho, hoy en día se suele añadir de forma automática[3]https://es.wikipedia.org/wiki/HTTP_Strict_Transport_Security, casi siempre.
El cifrado de la información
Para lograr esa comunicación segura la información intercambiada se hace ininteligible para todo aquel que no tenga la clave. A esto se le llama cifrar[4]https://es.wikipedia.org/wiki/Cifrado_(criptograf%C3%ADa) también se le llama encriptar, pero es más macabro la información. Tanto las peticiones de información que hace el navegador al sitio web, como la información de respuesta que el sitio web envía al navegador de vuelta están cifradas.
La clave de sesión
La clave secreta es acordada entre las dos partes, navegador y sitio web. A esa clave se le llama clave de sesión, porque se renegociará entre las partes cada poco tiempo. Si imaginamos que las claves son colores, la información cifrada por el servidor con un color sólo podrá ser descifrada por el navegador usando ese mismo color y ningún otro. Un adversario, alguien escuchando, sólo podrá ver la información intercambiada si conoce el color utilizado o es capaz de deducirlo. Este tipo de cifrado que usa una sóla clave se llama simétrico[5]https://es.wikipedia.org/wiki/Criptograf%C3%ADa_sim%C3%A9trica. Es muy adecuado porque el cifrado simétrico es muy rápido y seguro. Además nos permite, con ciertas cautelas, cifrar grandes cantidades de información.
Para lograr establecer una clave secreta compartida en presencia de terceros, las dos partes implicadas utilizan un protocolo, unas reglas de intercambio de clave[6]Una de los algorotmos más utilizado es Diffie-Hellman (https://simple.wikipedia.org/wiki/Diffie-Hellman_key_exchange). Siguiendo con la analogía de los colores, este protocolo se basa en la idea de que es fácil mezclar dos colores pero muy difícil separarlos después[7]En matemáticas hay varias operaciones equivalentes a mezclar los colores. Una habitual es la exponenciación discreta (https://es.wikipedia.org/wiki/Logaritmo_discreto).. Las dos partes se ponen de acuerdo públicamente en un color común inicial. Cada uno mezcla ese color común con su propio color secreto para obtener un color mezclado que enviará a la otra parte. Finalmente cada parte mezclará el color recibido con su color secreto obteniendo un color compartido igual que el de la otra parte. La siguiente figura lo explica muy bien:
En resumen, ambas partes mezclan el color común con los los dos colores secretos, uno de cada parte.
Este protocolo permite acordar el uso de una clave compartida de forma segura. Pero, en su versión básica o anónima, no garantiza con quién estoy intercambiando información. Es decir, no es autenticado. No se comprueba que las partes implicadas sean quienes dicen ser. Eso permitiría a un atacante colocarse entre las dos partes sin que ninguna de ellas se dé cuenta, creyendo ambas que sólo están ellas dos en la comunicación. Esto se llama ataque de intermediario[8]https://es.wikipedia.org/wiki/Ataque_de_intermediario o de hombre en medio.
La firma digital
Una solución para saber con quién estamos hablando, es que los mensajes enviados estén firmados digitalmente.
La firma digital es una de las aplicaciones de la criptografía asimétrica[9]La criptografía asimétrica ha supuesto una auténtica revolución en la sociedad. Sobre ella se ha construido el mundo digital que conocemos … Continue reading. En lugar de usar la misma clave para cifrar y descifrar una información, la criptografía asimétrica usa dos. Es decir, tenemos un par de claves vinculadas de tal forma que lo que cifra una de las claves sólo puede ser descifrado por la otra y ninguna otra. La clave que se usa para cifrar información es una clave secreta, privada. La otra es la clave pública, se la podemos entregar a todo el mundo. Con la clave pública que puede descifrar la información que he cifrada con la clave privada.
Hay que recalcar que en realidad estamos enviando dos objetos. Por un lado el mensaje público y por otro una firma de ese mensaje. Si cambio el mensaje la firma no será válida. La firma es el mensaje cifrado con la clave privada. Pero, la criptografía de clave asimétrica es lenta, muy lenta, y no puede cifrar mensajes muy largos. Por eso lo que se cifra, lo que se firma, es una representación del mensaje, llamada huella digital. Esta representación es otro mensaje de un tamaño fijo más pequeño, pero lo suficientemente grande para evitar colisiones. De esta forma todo mensaje, de cualquier tamaño, puede representarse por esa huella digital[10]https://es.wikipedia.org/wiki/Huella_digital_de_clave_p%C3%BAblica. El cambio de una sola letra en el mensaje cambiará completamente su huella[11]Además no se puede deducir el mensaje original a partir de la huella.
Esto quiere decir que aquí no hay confidencialidad de ningún tipo. Todo el mundo puede descifrar mis mensajes cifrados. Sólo tienen que usar la clave pública, que es pública. Tiene sentido, ya que se trata de una firma. Lo que sí garantiza[12]Más o menos probablemente dependiendo de en qué soporte (SmartCard, sistema centralizado, token de software) resida la clave privada, entre otras cosas es que sólo yo pude cifrar ese mensaje, como controlador exclusivo de esa clave secreta. Y es lo que equivale a una firma.
En resumen para firmar un mensaje calculamos su huella digital y la ciframos obteniendo un mensaje que llamaremos firma[13]El objeto de cifrado suele tener más información para evitar otro tipo de ataques.. Para verificar una firma la desciframos y verificamos que el valor obtenido es la huella digital del mensaje.
Los certificados digitales
Los navegadores tienen que obtener las claves públicas de las web a las que accedemos y estar seguros de que son auténticas para lograr establecer una comunicación segura. Cuando no podemos verificar si las claves públicas corresponden a la web a la que estamos intentando acceder nuestro tráfico podría ser interceptado y manipulado por un tercero sin darnos cuenta.
Un certificado digital vincula una clave pública con una identidad y otros datos. En el caso de un certificado de autenticación web la identidad se refiere al nombre de dominio[14]También existen certificados de autenticación web que incluyen el dueño legal de las claves privadas, el nombre de la organización lo que complica un poco la verificación de los datos a la hora … Continue reading. Además los certificados digitales incluyen la fecha desde la que es válido, que suele ser la fecha de emisión, y la fecha hasta será válido.
Las autoridades de certificación
Todos los datos que aparecen juntos en un certificado son firmados digitalmente por una autoridad de certificación (AC), también llamada entidad emisora[15]Existen otros modelos de certificación, Web of Trust, SPKI, DPKI, Blockchain PKI…. La AC se encarga de verificar la validez de todos esos datos incluidos en el certificado antes de emitirlo, antes de firmarlo[16]Estrictamente hablando la verificación de los datos la realiza una Autoridad de Registro (AR) pero lo vemos un poco más adelante.
La AC firma digitalmente el certificado usando su propio certificado. Como todo certificado es emitido por una AC se crea una cadena de confianza de autoridades de certificación. Esta cadena acaba cuando una AC emite un certificado que se verifica a sí mismo y que se llama certificado raíz[17]https://es.wikipedia.org/wiki/Cadena_de_confianza.
Establecer la identidad de un certificado sin una autoridad de certificación[18]https://www.usenix.org/legacy/publications/library/proceedings/sec96/full_papers/ellison/index.html es un viejo anhelo. Hasta hoy no lo hemos logrado, pero estamos cerca[19]https://es.wikipedia.org/wiki/Auto-Identidad_Soberana.
El poder de los navegadores
Todos los navegadores vienen preconfigurados con una serie de AC[20]Unas 650 directa o indirectamente actualmente, https://www.eff.org/observatory[21]También las llaman entidades emisoras que permiten verificar y aceptar certificados de autenticación de sitios web emitidos por esas AC. Cada navegador tiene su propio procedimiento para añadir o eliminar las AC que vienen preconfiguradas. Un certificado emitido por una AC puede ser aceptado en un navegador y no en otro, y esto suele crear problemas extraños. Al final, un puñado de personas responsables de cada navegador deciden qué AC son incluidas en ese “pequeño” listado de AC confiables que garantizan nuestra seguridad en las comunicaciones. Siempre ha sido así en el mundo humano.
El poder de la autoridades de certificación
Las AC pueden emitir certificados para cualquier dominio a su discreción, como hizo Symantec emitiendo certificado “de prueba” con el dominio de google[22]https://arstechnica.com/information-technology/2017/03/google-takes-symantec-to-the-woodshed-for-mis-issuing-30000-https-certs/. Esos certificados podrían haber sido usados para lanzar ataques de phising muy efectivos.
Con el poder que tienen las AC las hace objetivos muy apetecibles para los hackers, como lo fue DigiNotar[23]https://www.wired.com/2011/09/diginotar-bankruptcy/. También los gobiernos pueden abusar de su poder como hizo Siria intentando un ataque de intermediario con FaceBook[24]https://www.eff.org/deeplinks/2011/05/syrian-man-middle-against-facebook.
Una AC puede ser deshonesta, o puede estar comprometida de alguna forma[25]https://www.eff.org/es/deeplinks/2011/03/iranian-hackers-obtain-fraudulent-https https://www.theregister.com/2012/02/09/tustwave_disavows_mitm_digital_cert/ … Continue reading. Sea queriendo o sin querer, una AC comprometida podrá emitir certificados con claves públicas falsas, para cualquier dominio. Todo navegador que confie en esa AC maliciosa aceptará sin pestañear los certificados por ella emitidos[26]Es el eslabón más débil. Comprometer una AC supone comprometer todo el sistema. Un atacante puede falsificar certificados para cualquier web que desee y no habrá forma de diferenciarlos de certificados auténticos.
La infraestructura de clave pública
La infraestructura de clave pública[27]Tecnología con 40 años de existencia… son las políticas y procedimientos, el software, el hardware que se necesitan para gestionar certificados digitales. Gestionar quiere decir cómo emitirlos, usarlos, almacenarlos, revocarlos, eliminarlos…
Algunas de las funciones de una AC pueden ser delegadas. Por ejemplo, la AC delega en la autoridad de registro (AR) la verificación de los datos de identidad que aparecen en un certificado.
Las entidades de validación (AV) proporcionan los servicios necesarios para comprobar que un certificado sigue siendo válido en un momento determinado. El certificado tiene entre sus datos un periodo de validez. No hace falta una AV para verificar si el certificado está dentro de ese periodo, más allá de tener un reloj correctamente sincronizado[28]El tiempo, el reloj es una de las primeras causas de ataques informáticos. Mantener el reloj del sistema sincronizado es todo un reto. Ver NTP, sdwdate. Pero sí en los casos en los que el certificado o alguno de sus datos dejan de ser válidos por alguna otra razón.
El problema de la infraestructura de clave pública
El modelo de infraestructura pública es frágil[29]https://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf [30]https://blog.cryptographyengineering.com/2012/02/28/how-to-fix-internet/. Por una parte cualquier AC puede emitir un certificado para cualquier dominio. Por otra parte, no hay forma de saber qué certificados ha emitido una AC. Para reducir el problema se han propuesto muchas soluciones[31]https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning, que no han funcionado. Actualmente se usa un registro público transparente y verificable de la emisión de certificados de cada AC[32]https://certificate.transparency.dev/ para reducir los certificados emitidos por error o malintencionadamente[33]Estos registros acabarán utilizando la blockchain en un futuro próximo..
El estado de revocación un certificado
El tiempo de vida de un certificado es relativamente largo, en el orden de meses. Algún dato del certificado puede dejar de ser correcto, se puede perder el control de la clave privada asociada al certificado, la entidad emisora puede haber sido comprometida, se ha perdido… Pero el certificado es un objeto inmutable. Por eso se establecen distintos mecanismos que permiten consultar el estado del certificado. Por lo menos el estado que tenía hace poco tiempo, en el orden de horas.[34]Añadir estos servicios de verificación es muy cuestionable y posiblemente no sea una buena solución. Reducir el tiempo de validez de un certificado es la única solución. Un certificado será … Continue reading
Un certificado está “revocado” cuando un pierde su validez por otras causas que no sean la expiración.
Los servicios para verificar el estado de revocación de un certificado los proporciona la AV y los medios para acceder a ellos suelen ir en el propio certificado. Estos servicios son otro talón de aquiles de la infraestructura de clave pública.
Un navegador no puede estar seguro de que los servidores de la AV serán accesibles para verificar el estado de un certificado. Por ejemplo, un portal captivo sólo permite autenticarse en una dirección HTTPS pero bloquea el tráfico a cualquier otra dirección, incluyendo los servicios de consulta de revocación del certificado. Si el navegador no acepta el certificado cuando no pueda verificar su estado no se podrá acceder al sitio web, dejando de funcionar. Por otra parte, un corte, por pequeño que sea, de los servicios de consulta de estado supone un punto único de fallo[35]Pese a que se suelen utilizar servicios de alta disponibilidad.
Por eso muchos navegadores consideran los errores de red a la hora de consultar el estado de revocación de un certificado como fallos que simplemente son ignorados[36]“soft-fails”. Además los costes de la verificación son mayores tiempos de conexión, páginas más lentas y posibles problemas de privacidad porque las AV pueden registrar los dominios consultados y desde qué ip… Por eso algunos navegadores[37]https://github.com/agl/crlset-tools utilizan un mecanismo que envía las listas de certificados revocados de todas la AC a cada navegador, que complica ligeramente las cosas a un atacante.
La listas de revocación de certificados
Uno de los primeros servicios para la consulta del estado de revocación de un certificado fue utilizar una lista (CRL). En esa lista aparece el identificador del certificado junto a un estado de revocación. Si el certificado no aparece en la lista será válido. Los certificados suelen incluir uno o varios servicios desde los que descargar esas listas.
Las listas se actualizan cada cierto tiempo para reflejar los cambios. Uno de los problemas con estas listas es que crecen de manera desmedida con el tiempo[38]Y todavía más siguiendo las recomendaciones de algunas normas que quieren mantener los certificados revocados en las listas incluso cuando estos han expirado. Las listas incrementales sólo … Continue reading, pueden ser problemáticas respecto a la privacidad de datos, o simplemente no están lo suficientemente actualizadas…
La consulta de revocación de un certificado en línea
Este pequeño caos con las listas de revocación desembocó en la creación de un nuevo servicio que permitiera comprobar el estado de un certificado en concreto directamente (OCSP)[39]No estoy muy seguro de por qué razón en este momento el servicio no fue simplemente mandar una lista con los certificados de los que se quiere información y se creó una nueva estructura … Continue reading. En lugar de descargar una lista cada cierto tiempo los navegadores pueden realizar las consultas cada vez y sólo para el certificado que están usando. Pero esto creó una dependencia mucho mayor entre la AV y el navegador. Los ataques de denegación de servicio son más fáciles. La disponibilidad del servicio se vuelve más crítica. La privacidad empeora…
Para aliviar alguno de estos problemas se establecen protocolos para mandar el estado de revocación junto con el certificado del sitio web[40]OCSP Stapling pero crean sus propios problemas.
Cada día aparecen nuevas propuestas para la consulta del estado de revocación de un certificado, como solución específica o englobada en una solución más general[41]smartCert,EthIKS,COINIKS,CertCoint,BlockPKI,Gossip,PoliCert,PKISN….
La cadena de bloques y los contratos inteligentes
La cadena de bloques (blockchain) es un registro público y descentralizado de datos que se actualiza, sólo añadiendo entradas en forma de transacciones[42]Quiere decir que sólo se pueden añadir nuevos datos, no modificar los anteriores, que son inmutables., mediante el consenso de todos los participantes. Los datos se almacenan de forma redundante en muchos sitios. Bitcoin, el precursor de la blockchain, permite mantener un registro público de los intercambios de valor entre los participantes. Es muy difícil de censurar ya que no tiene una entidad central que lo controle. Será muy difícil prohibirlo sin que se considere un ataque a la propia libertad de expresión y el derecho a comunicarnos. Ethereum por su parte hace uso de una blockchain para mantener un consenso no sólo sobre la información, sino sobre pequeñas aplicaciones que manipulan esa información, convirtiéndose en una especie de ordenador global público compartido. Ethereum llama a esas pequeñas aplicaciones contratos inteligentes.
La blockchain proporciona nuevos casos de uso que previamente no se podían resolver de forma satisfactoria Proporciona inmutabilidad, una vez escrito un registro en un bloque no se puede alterar porque requeriría alterar todos los bloques anteriores que requieren el consenso de todos los participantes. Es un sistema descentralizado que evita muchos ataques como la denegación de servicio. Es transparente, la blockchain es visible públicamente. Es rápida y más barata, en relación a sistemas equivalentes con las mismas garantías.
La lista de certificados revocados descentralizada
Vamos a explorar las posibilidades de utilizar blockchain como registro del estado de revocación de los certificados emitidos por una AC. Lo llamaremos Decentralized Certificate Revocation List (DCRL).
Definiremos y desplegaremos un contrato inteligente de Ethereum para gestionar la lista. Definiremos una nueva extensión del certificado que incluya la dirección del contrato inteligente. Crearemos unos certificados de ejemplo e implementaremos las herramientas para revocar un certificado y para consultar su estado.
Parte II
Los nodos y los clientes de Ethereum
Un nodo de ethereum es una aplicación que permite interactuar con Ethereum. Una vez instalada permite verificar las transacciones de cada bloque y enviar a la red nuevas transacciones. Hay distintas implementaciones de clientes de Ethereum. Aquí vamos a usar el cliente geth[43]https://geth.ethereum.org/docs/getting-started. Un nodo puede lanzarse con distintos modos. El modo completo (full) almacena todos los datos de la blockchain, participa en la validación de bloques, verifica bloques y estados… El modo ligero sólo valida los datos de las cabeceras de los bloques y se usa en dispositivos embebidos o de pocos recursos.
Nosotros vamos a utilizar el modo “fast” que sólo utiliza el estado más reciente de la blockchain.
Descargamos el cliente de la web de Ethereum. Dejamos para la reflexión cómo estaremos seguros de que hemos accedido a la web auténtica y que hemos descargado un paquete legítimo.
https://geth.ethereum.org/downloads/
Por ejemplo usando wget para una distribución linux 64bits
wget https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.25-e7872729.tar.gz
Descomprimimos el paquete y accedemos al directorio
tar xvf geth-linux-amd64-1.9.25-e7872729.tar.gz
cd geth-linux-amd64-1.9.25-e7872729
y lanzamos el nodo utilizando esta línea de comandos
$ geth --goerli --syncmode "light" --http --
http.corsdomain="https://remix.ethereum.org" --allow-insecure-unlock
Algunos de los parámetros importantes de geth
–http | Activa el servicio JSON-RPC, que permite a otras aplicaciones usar el nodo vía API |
–http.corsdomain | Sólo se permitirá el acceso a la API desde “https://remix.ethereum.org“, que será el entorno con el que desplegamos el contrato inteligente |
–goerli | Utilizaremos la red de pruebas Görli. Ethereum dispone de varias redes de pruebas y una de producción. Görli es una red proof-of-authority que funciona con clientes Parity, Geth y otros |
–syncmode | Utilizaremos el modo de sincronización “light”, por defecto es “fast” |
–datadir | El directorio donde se almacenarán los datos de la blockchain. Ocupará unos 12GB si utilizamos un nodo “fast” y 500MB si usamos un nodo “light”. Si no no especificamos usará el directorio por defecto que es ~/.ethereum/goerli |
–cache | Aumentar a 2048 la memoria mejora el rendimiento en caso de sincronización “fast” |
–allow-insecure-unlock | Permite desbloquear un monedero al mismo tiempo que se usa la API, lo que no es recomendable fuera de desarrollo. |
console | Lanza una consola JavaScript para interactuar con el nodo |
El modo “light” es experimental pero suficientemente estable como para nuestro cometido.
INFO [02-12|09:27:12.511] Starting Geth on Görli testnet...
[...]
WARN [02-12|09:27:12.689] Light client mode is an experimental feature
Al lanzar el nodo comenzará a sincronizarse con la red automáticamente. Recuerda que esa sincronización llevará varias horas en el caso de que el modo sea “fast”.
Para interactuar con el nodo desde otra terminal utilizamos el comando attach:
$ geth --goerli attach
Welcome to the Geth JavaScript console!
[..]
To exit, press ctrl-d
Al introducir en consola el comando eth.syncing obtendremos el estado de sincronización del nodo o false si está completamente sincronizado. eth es un objeto que permite interactuar con los contratos inteligentes y la propia blockchain.
> eth.syncing
{
currentBlock: 213539,
highestBlock: 4264547,
knownStates: 511823,
pulledStates: 502449,
startingBlock: 0
}
Con el comando eth.blockNumber obtendremos el último bloque procesado por nuestro nodo.
> eth.blockNumber
4269342
La cartera
Para enviar transacciones a la blockchain necesitamos unas credenciales además del nodo. Las credenciales son una clave pública y otra privada. A partir de la clave pública obtendremos un número de cuenta o dirección(address). Utilizando mensajes firmados digitalmente con nuestra clave privada enviamos operaciones en forma de transacciones a la blockchain.
El sitio donde guardamos esas claves se llama cartera, billetera o monedero (wallet) y tiene asociado un balance, unos ether, que nos permitirán enviar las transacciones a la red. Crear una nueva cuenta no requiere de ningún tipo de autorización. Ethereum es una red no permisionada.
No tenemos ninguna cuenta en nuestro nodo local. Para añadir una usamos el objeto personal que se encarga de interactuar con las cuentas del nodo:
> personal.newAccount()
Establecemos una contraseña, que podemos dejar en blanco para las pruebas. Para obtener las cuentas que tenemos escribimos:
> personal.listAccounts
["0x673ce1bda1ca6a7d969b8f44e44d78ce9ef11691"]
aunque también podemos usar eth.accounts, más habitual. El balance de la cuenta reside en la blockchain, no en la cuenta y por tanto para obtenerlo utilizamos método getBalance del objeto eth, que nos dará los Wei[44]1 ether = 10^18 Wei (un trillón) en la cuenta.
> eth.getBalance(eth.accounts[0])
0
Para añadir fondos accedemos a alguno de los servicios gratuitos de suministro para la red Görli. Introduciremos nuestra dirección y amablemente nos transferirán una pequeña cantidad de ethers. En producción utilizaremos algún exchange para adquirir ethers a cambio de euros o dólares.
Por ejemplo, podemos acceder a https://goerli-faucet.slock.it/
En unos instantes tendremos los fondos disponibles en nuestra cuenta.
El contrato inteligente
Ethereum ejecutar pequeñas aplicaciones mediante una máquina virtual[45]https://ethereum.org/es/developers/docs/evm/ (EVM). Las aplicaciones pueden entenderse como una máquina de estados distribuida. La EVM permite modificar esa máquina de estados global mediante instrucciones de bajo nivel u opcodes. Existen varios lenguajes de programación que compilan a instrucciones de EVM. El más usado es Solidity[46]https://es.wikipedia.org/wiki/Solidity. Es un lenguaje orientado a objetos con tipos específicos, modificadores de funciones para crear precondiciones, gestión de eventos…
Nuestro contrato inteligente es muy sencillo. Contiene la lista de certificados que hayan sido revocados. Si aparecen en la lista han sido revocados, sin más información inicial. Cada AC gestionará el contrato inteligente que gestiona la lista
Los certificados se localizan mediante su identificador de sujeto (Subject Key Identifier, SKID). El SKID es una extensión de los certificados que se calcula a partir de su clave pública[47]Puede calcularse de otra forma siempre pero es habitual que sea derivado de la clave pública.
Extensions:
2.5.29.14 (Subject key identifier)
Identifier: ee:09:e5:4e:30:60:2b:fa:c7:52:78:86:b9:b9:9e:fb:a6:7f:20:0b
El código del contrato inteligente tiene un mapa que asocia un entero de 256bits con un valor booleano. Tiene dos funciones, una para la consulta del estado de una certificado y otra para revocar un certificado, ambos identificados mediante el SKID. El método revoke sólo podrá ser llamado por el dueño del contrato.
pragma solidity >=0.7.0 <0.8.0;
contract DCRL {
address owner;
constructor() {
owner = msg.sender;
}
mapping(uint256 => bool) revoked;
function revoke(uint256 id) public {
require(owner == msg.sender);
revoked[id]=true;
}
function has(uint256 id) public view returns (bool){
return revoked[id];
}
}
El entorno de desarrollo
Para desarrollar contratos inteligentes podemos usar entornos como truffle[48]https://www.trufflesuite.com/, que nos permite tener un ciclo de desarrollo sano. En este artículo usaremos directamente un editor online llamado Remix[49]https://remix-project.org/, que nos permitirá compilar, ejecutar, analizar y desplegar el contrato a través de nuestro nodo local.
Accederemos a https://remix.ethereum.org/?#gist=505a93da7b10ed3438a0dcc68832b337 donde veremos el entorno Remix como se muestra a continuación[50]También puedes instalarlo localmente: https://github.com/ethereum/remix-ide, con el contrato DCRL.sol precargado desde gist.
A la izquierda podemos acceder al árbol del proyecto, el compilador, el acceso al nodo para enviar transacciones y contratos y el gestor de complementos. En el centro tenemos el panel principal y debajo una terminal.
Podemos editar el contrato, cada vez que lo guardemos se autocompilará mostrando los posibles errores de sintaxis.
Para desplegar el contrato accederemos a la pestaña “Deploy & Run Transactions”. Estableceremos como entorno nuestro nodo local. Para ello seleccionamos “Web3 Provider” en Environment. Dejaremos el “Web3 Provider Endpoint” en su valor por defecto “http://127.0.0.1:8545”. Tras ello aparecerán las cuentas de nuestro nodo junto con su balance en la sección “Account”. Seleccionaremos la que tenga fondos disponibles si tenemos más de una.
Desde la consola de nuestro nodo local desbloquearemos la cuenta para poder firmar la transacción usando el método unlockAccount de personal:
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x673ce1bda1ca6a7d969b8f44e44d78ce9ef11691
Passphrase:
true
A continuación pulsaremos el botón “Deploy” desde el entorno.
Desplegar un contrato es enviar una transacción a la red Ethereum a través de nuestro nodo local. El deploy no es instantáneo, la red tiene que añadir la transacción a un bloque y llegar a un consenso sobre su validez. Una vez llegado al acuerdo nuestro contrato está disponible globalmente en una dirección.
Podemos ver el estado de las transacciones usando un explorador de transacciones. Podemos obtener directamente una url de acceso en la consola del entorno:
https://goerli.etherscan.io/tx/…
Una vez desplegado podemos interactuar con el contrato directamente desde el propio entorno de desarrollo, donde aparecerán los distintos métodos disponibles en el contrato.
Si introducimos un id en el método “has” y pulsamos el botón del método lanzaremos la llamada obteniendo el resultado esperado en el campo “decoded output” de la consola del entorno:
{
"0": "bool: false"
}
Si ahora utilizamos el método revoke, tras desbloquear la cuenta, con un parámetro y consultamos de nuevo su estado con el método has obtendremos true indicando que el certificado con ese SKID ha sido revocado.
Como ejercicio demostrar que otra cuenta no puede actualizar la lista, crear usuario, etc.
La seguridad de un contrato inteligente
Programar correctamente un contrato inteligente es un trabajo especialmente delicado. No solamente por los bugs que puedan tener sino por su propio diseño. El software ha salvado muchas veces la situación. Si la perseverance[51]https://www.nasa.gov/perseverance tiene un problema de software, se le enviará una actualización. Si tiene un problema de hardware, probablemente se arreglará también con una actualización de software. Estamos tan acostumbrados a las actualizaciones de software que olvidamos las consecuencias de un software que no se puede actualizar. Un contrato desplegado en la blockchain es inmutable. Sin embargo, necesitamos cierto grado de mutabilidad para corregir posibles bugs[52]https://medium.com/firmonetwork/3-famous-smart-contract-hacks-you-should-know-dffa6b934750 o realizar mejoras.
Un contrato inteligente es “actualizable” creando un nuevo contrato y transfiriendo el estado del viejo contrato al nuevo. Pero migrar el estado puede ser caro, la dirección del contrato cambiará y el periodo de tiempo en el que el viejo y nuevo contrato coexistan es un gran problema.
La alternativa es usar un contrato (proxy o representante) para almacenar el estado y redirigir las llamadas a otro contrato llamado implementación que almacena la lógica de negocio. De esta manera podemos actualizar la lógica de negocio sin tener que realizar migraciones más allá de indicarle al proxy qué lógica usar.
Proyectos como OpenZeppelin[53]https://openzeppelin.com/ proporcionan un framework para simplificar la programación de contratos inteligentes actualizables.
Pero hay que advertir que reducir el esfuerzo de programar adecuadamente porque el software se puede actualizar es un error de consecuencias muy graves[54]https://es.wikipedia.org/wiki/Error_de_software#Casos_notables , https://es.wikipedia.org/wiki/Ariane_5#Falla_del_ARIANE_5G_de_1996. Y en el ámbito de los contratos inteligentes son habituales los robos o bloqueos irreversibles de fondos[55]https://arxiv.org/pdf/1806.01143.pdf.
Un contrato inteligente debe utilizar todas las herramientas a su alcance para garantizar su seguridad. Incluyendo auditorías, análisis estáticos y dinámicos de código, tests…
Desde el propio entorno Remix podemos usar plugins que proporcionan análisis básicos de seguridad y estilo. Por ejemplo, usando Solint y Solidity Static Analysis obtenemos los siguientes informes:
Los informes obtenidos son sólo eso, informes con sugerencias o aspectos a revisar. No sería la primera vez que hacer caso a ciegas a estos análisis provoca un problema muy serio[56]En el 2003 dos líneas de código fueron eliminadas, del proyecto OpenSSL, tras la sugerencia de dos herramientas de análisis estático de código (valgrind y purify). Esto provocó que la entropía … Continue reading. Pero tampoco se deben ignorar las advertencias a la ligera. Discutir cada advertencia con otras personas competentes y con calma suele ser lo más recomendable.
La extensión para el certificado
Incorporaremos la dirección del contrato inteligente que acabamos de desplegar a los certificados mediante la definición de una nueva extensión.
El estándar ASN.1[57]https://es.wikipedia.org/wiki/ASN.1 se utiliza para la descripción de estructuras de datos de forma independiente a la máquina. La estructura de los certificados se suele expresar utilizando esta sintaxis. Nuestra extensión será la siguiente:
DCRL EXTENSION ::= {
SYNTAX DCRLURIList
IDENTIFIED BY id-dcrl }
DCRLURIList ::= SEQUENCE OF DCRLURI
DCRLURI ::= IA5String
Los OIDS son una secuencia de números separados por punto, jerárquicos que permiten identificar objetos. En esta extensión utilizaremos:
id-enterprise OBJECT IDENTIFIER ::= {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1)}
id-espublico OBJECT IDENTIFIER::= {id-enterprise espublico(47281)}
id-esfirma-rd OBJECT IDENTIFIER::= {espublico esfirma-rd(555)}
id-certs OBJECT IDENTIFIER ::= {id-esfirma-rd certs(1)}
id-dcrl OBJECT IDENTIFIER ::= {id-certs dcrl(1)}
Que corresponden a la siguiente tabla
1.3.6.1.4.1.47281 | Espublico |
1.3.6.1.4.1.47281.555 | ESFIRMA I+D+i Identifier |
1.3.6.1.4.1.47281.555.1 | x509Cert |
1.3.6.1.4.1.47281.555.1.1 | Decentralized Certificate Revocation Log (DCRL) |
La extensión contendrá una lista, una secuencia, de identificadores de recursos uniforme[58]https://es.wikipedia.org/wiki/Identificador_de_recursos_uniforme (URI). Cada URI definirá el acceso a un servicio de consulta de una blockchain.
Definiremos la URI de acceso al contrato inteligente DCRL de la red como
dcrl:ethereum:<dirección del contrato>
En nuestro caso la URI de consulta para el contrato inteligente que acabamos de desplegar será:
dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645
La visualización de la extensión DCRL
Para poder visualizar la extensión DCRL de un certificado fácilmente añadiremos la lógica al proyecto XRAY-509[59]https://github.com/antik10ud/xray509 es un proyecto para visualizar certificados. Añadimos el procesador de la extensión DCRLProc,
public class DCRLProc extends BaseExtensionProc {
@Override
public Item processContent(Context ctx, Extension ext) throws IOException {
Item out = new Item();
if (ext.extnValue != null) {
DCRLSequence i = new DCRLSequence();
i.decode(ext.extnValue.from, ext.extnValue.value, true);
int index = 0;
for (BerIA5String name : i.seqOf) {
out.prop(ItemHelper.index(index++), new Item(new TaggedString("uri").addIndexTag(index), new TaggedString(String.valueOf(name)).addTag("type", "IA5String")));
}
}
return out;
}
}
Añadiremos el procesado a la lista de extensiones conocidas en el método registerExtensions de la clase Context.
registerExtension("1.3.6.1.4.1.47281.555.1.1",new DCRLProc());
Como ejercicio realizar el testing adecuado a esta nueva funcionalidad
La emisión del certificado con soporte DCRL
Emitir un certificado digital consiste en generar un par de claves, crear una solicitud de firma de certificado (CSR) y enviar el CSR a la AC para que genere el certificado.
Vamos a lanzar nuestra propia AC de pruebas basada en OpenSSL. Para ello crearemos un certificado raíz.
$ openssl genrsa -out ca.key 2048
[..]
Country Name (2 letter code) [AU]:ES
State or Province Name (full name) [Some-State]:Aragon
Locality Name (eg, city) []:Zaragoza
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Espublico
Organizational Unit Name (eg, section) []:ESFIRMA I+D+i
Common Name (e.g. server FQDN or YOUR name) []:TEST CA
Email Address []:
Utilizando la herramienta de visualización podemos ver la estructura detallada del certificado generado:
$ xray-cert ca.crt
Version: 2 (v3)
SerialNumber: 9563599858331462912 (hex: 0x84b8bb66a9d2ad00, bits: 72)
Signature:
algo: 1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
params: NULL
Issuer:
2.5.4.6 (countryName,C): ES (type: printableString)
2.5.4.8 (stateOrProvinceName,ST): Aragon (type: utf8String)
2.5.4.7 (localityName,L): Zaragoza (type: utf8String)
2.5.4.10 (organizationName): Espublico (type: utf8String)
2.5.4.11 (organizationalUnitName): ESFIRMA I+D+i (type: utf8String)
2.5.4.3 (commonName,CN): TEST CA (type: utf8String)
Subject:
2.5.4.6 (countryName,C): ES (type: printableString)
2.5.4.8 (stateOrProvinceName,ST): Aragon (type: utf8String)
2.5.4.7 (localityName,L): Zaragoza (type: utf8String)
2.5.4.10 (organizationName): Espublico (type: utf8String)
2.5.4.11 (organizationalUnitName): ESFIRMA I+D+i (type: utf8String)
2.5.4.3 (commonName,CN): TEST CA (type: utf8String)
Validity:
Duration: 1 month 2 days
NotBefore: 2021-02-12T13:20:32Z
NotAfter: 2021-03-14T13:20:32Z
[...]
Preparamos la configuración de la CA para emitir certificados con soporte DCRL.
Creamos el fichero ca.conf:
[ ca ]
default_ca = test_ca
[ test_ca ]
serial = ./serial
database = ./index.txt
new_certs_dir = ./newcerts
certificate = ./ca.crt
private_key = ./ca.key
default_md = sha256
default_days = 365
policy = test_policy
[ test_policy ]
countryName = supplied
stateOrProvinceName = supplied
organizationName = supplied
organizationalUnitName = optional
y el fichero cert.extensions.conf en el que definiremos la extensión DCRL con la URI de nuestro contrato inteligente.
basicConstraints=CA:FALSE
subjectAltName=@my_subject_alt_names
subjectKeyIdentifier = hash
1.3.6.1.4.1.47281.555.1.1=ASN1:SEQUENCE:DCRLExt
[DCRLExt]
uri=IA5STRING:dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645
[ my_subject_alt_names ]
DNS.1 = test.esfirma.com
Generamos las claves y el CSR para el certificado final. Para ello vamos a añadir un fichero cert.conf con los datos que nos gustaría que aparecieran en el certificado:
[ req ]
default_bits = 2048
default_keyfile = cert.key
encrypt_key = no
default_md = sha256
prompt = no
utf8 = yes
distinguished_name = the_distinguished_name
req_extensions = the_extensions
[ the_distinguished_name ]
C = ES
ST = Aragon
L = Zaragoza
O = Espublico
OU = Esfirma I+D+i
[ the_extensions ]
basicConstraints=CA:FALSE
subjectAltName=@the_subject_alt_names
subjectKeyIdentifier = hash
[ the_subject_alt_names ]
DNS.1 = test.esfirma.com
Creamos el CSR para enviarselo a la AC
$ openssl req -new -out cert.csr -config cert.conf
La AC verificará la información contenida en el CSR, validará la identidad del solicitante y emitirá un certificado.
$ openssl ca -config ca.conf -out cert.crt -extfile cert.extensions.conf -in cert.csr
El nuevo certificado contendrá una extensión DCRL.
$ xray-cert cert.crt
[...]
Issuer:
2.5.4.6 (countryName,C): ES (type: printableString)
2.5.4.8 (stateOrProvinceName,ST): Aragon (type: utf8String)
2.5.4.7 (localityName,L): Zaragoza (type: utf8String)
2.5.4.10 (organizationName): Espublico (type: utf8String)
2.5.4.11 (organizationalUnitName): ESFIRMA I+D+i (type: utf8String)
2.5.4.3 (commonName,CN): TEST CA (type: utf8String)
Subject:
2.5.4.6 (countryName,C): ES (type: printableString)
2.5.4.8 (stateOrProvinceName,ST): Aragon (type: utf8String)
2.5.4.10 (organizationName): Espublico (type: utf8String)
2.5.4.11 (organizationalUnitName): Esfirma I+D+i (type: utf8String)
[...]
Extensions:
2.5.29.19 (Basic constraints)
None
2.5.29.17 (Subject alternative name)
DNSName: test.esfirma.com (type: IA5String)
2.5.29.14 (Subject key identifier)
Identifier: e2:a4:1b:59:70:00:ac:93:93:8b:4e:1d:88:cc:77:3e:
6c:69:01:f4
1.3.6.1.4.1.47281.555.1.1 (DCRL - Decentralized Certificate Revocation Log)
[0] uri: dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645 (type: IA5String)
[...]
La herramienta para consultar la DCRL
Añadiremos al proyecto XRAY dos nuevas herramientas, una para consultar el estado de revocación de un certificado mediante la consulta de la extensión DCRL y otra para revocar el certificado.
Para ello añadimos a pom.xml la dependencia web3j. Una librería ligera y modular para interactuar con contratos inteligentes en la red Ethereum[60]https://github.com/web3j/web3j.
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>5.0.0</version>
</dependency>
Para generar generar un wrapper a partir del contrato inteligente añadimos al pom el siguiente plugin.
<plugin>
<groupId>org.web3j</groupId>
<artifactId>web3j-maven-plugin</artifactId>
<version>4.6.5</version>
<configuration>
<packageName>com.k10ud.xray509.blockchain.model</packageName>
<sourceDestination>src/main/java</sourceDestination>
<nativeJavaType>true</nativeJavaType>
<outputFormat>java,bin</outputFormat>
<soliditySourceFiles>
<directory>src/main/resources/sol</directory>
<includes>
<include>**/*.sol</include>
</includes>
</soliditySourceFiles>
</configuration>
</plugin>
Generamos el wrapper con el comando
mvn web3j:generate-sources
Definiremos nuestro comando xray-dcrs que tan sólo necesitará como parámetros el certificado a consultar. Opcionalmente se podrá especificar la dirección del servicio JSON-RPC del nodo cliente de Ethereum que desamo usar, siendo el nodo local el defecto,
@CommandLine.Command(name = "xray-dcrs",
header = "xray-dcrs 0.0.1",
showDefaultValues = true,
description = "x509 decentralized certificate revocation store"
)
public static class Args extends CommonArgs {
@CommandLine.Parameters(arity = "1", paramLabel = "SOURCE", description = "X509Certificate with dcrl extension")
private String[] inputFile;
@CommandLine.Option(names = {"--http-service"}, description = "Ethereum JSON-RPC Service Address")
public String httpService;
}
[...]
String contractAdddress = contractURI.substring(DCRL_ETHEREUM.length());
Web3j web3 = Web3j.build(new HttpService(app.httpService != null ? app.httpService : "http://localhost:8545/"));
Credentials credentials = Credentials.create("00000000000000000000000000000000");
DCRL contract = DCRL.load(contractAdddress, web3, credentials, new DefaultGasProvider());
boolean revoked;
try {
revoked = contract.has(new BigInteger(1, contracts.skid)).send();
entry.prop("revoked", revoked);
} catch (Exception e) {
entry.prop("error", "smartc entry call: " + Exceptions.getSmartExceptionMessage(e));
}
Extraemos la lista de URIs de la extensión del certificado usando la consulta.
MATCH
Extensions/1.3.6.1.4.1.47281.555.1.1/$contracts:=uri,
Extensions/2.5.29.14/$skid:=Identifier
RETURN $contracts, $skid
Añadimos al pom el comando
<program>
<mainClass>com.k10ud.cli.XrayDCRL</mainClass>
<name>xray-dcrl</name>
</program>
Compilamos el proyecto.
mvn package
Y lo probamos con nuestro certificado de pruebas.
$ xray-dcrl cert.crt
skid: E2A41B597000AC93938B4E1D88CC773E6C6901F4
dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645
revoked: false
El comando ha analizado el certificado, determinado su SKID, extraído de su extensión DCRL la URI de consulta y conectado con el nodo local de Ethereum para verificar el estado de revocación del certificado.
La herramienta para revocar un certificado DCRL
La herramienta leerá un certificado, extraerá la URI de consulta de la DCRL y creará una transacción para establecer el certificado como revocado. El comando necesitará el certificado a revocar y la localización de la wallet para firmar la transacción. Opcionalmente podemos establecer el límite de gas y su precio para la ejecución de la transacción[61]Los contratos inteligentes de Ethereum son Turing-completos. Para evitar bucles infinitos y otros problemas, la ejecución de los métodos del contrato requiere un límite de gas, que una forma de … Continue reading.
@CommandLine.Command(name = "xray-dcrl-publish",
header = "xray-dcrl-publish 0.0.1",
showDefaultValues = true,
description = "Decentralized Certificate Revocation Log DCRL publisher"
)
public static class Args {
@CommandLine.Option(names = {"-h", "--help"}, usageHelp = true,
description = "Displays this help message and quits.")
public boolean helpRequested = false;
public Context context;
@CommandLine.Parameters(arity = "1", paramLabel = "SOURCE", description = "X509Certificate with dcrl extension")
private String[] inputFile;
@CommandLine.Option(names = {"--wallet-pass"}, description = "Wallet password... ONLY FOR TESTING")
public String wpass;
@CommandLine.Option(required = true, names = {"--wallet-source"}, description = "Wallet file source")
public String wsource;
@CommandLine.Option(names = {"--gas-price"}, description = "Tx Gas Price, -1 auto estimate")
public BigInteger gasPrice = BigInteger.valueOf(-1);
@CommandLine.Option(names = {"--gas-limit"}, description = "Tx Gas Limit")
public BigInteger gasLimit = BigInteger.valueOf(100_000);
@CommandLine.Option(names = {"--http-service"}, description = "Ethereum JSON-RPC Service Address")
public String httpService;
}
El comando cargará la wallet a partir de los parámetros.
Credentials credentials;
try {
credentials = WalletUtils.loadCredentials(app.wpass != null ? app.wpass : "", app.wsource);
} catch (Exception e) {
log("error", "credentials: " + Exceptions.getSmartExceptionMessage(e));
return;
}
[...]
price = web3.ethGasPrice().send().getGasPrice();
[...]
DCRL contract = DCRL.load(contractAdddress, web3, credentials, new StaticGasProvider(price, app.gasLimit));
TransactionReceipt tx = contract.revoke(new BigInteger(1, contracts.skid)).send();
Una vez añadido el comando al pom y empaquetado el proyecto procederemos a recovar el certificado de prueba. El fichero de la wallet estará en ~/.ethereum/goerli/keystore
$ xray-dcrl-revoke --wallet-source wallet.file cert.crt
skid: E2A41B597000AC93938B4E1D88CC773E6C6901F4
gas_estimated_price: 20000000000
status: 0x1
from: 0x673ce1bda1ca6a7d969b8f44e44d78ce9ef11691
to: 0xd807991602ec9269e233e54188a5b9a6ed904645
contract_address: null
hash: 0x7b2be3df8dedb966fefb3c207eae0cde610b2b04abf28f2a315209d57cf76ff4
number: 4270979
used: 43326
cumulative: 94316
revert_reason: null
root: null
hash: 0x8f0d733160ebb285e6e41b9a4f749bc6fc2f82bc493eddbf50eabd5a5650f79b
index: 1
dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645: revoked: true
Tras unos instantes la transacción será incorporada a un bloque de la red Ethereum de pruebas. Podemos consultar el estado de la transacción en etherscan:
https://goerli.etherscan.io/tx/…
Si volvemos a consultar el estado del certificado obtendremos la marca de revocado.
$ xray-dcrl cert.crt
skid: E2A41B597000AC93938B4E1D88CC773E6C6901F4
dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645
revoked: true
El certificado completo
El certificado de prueba que hemos utilizado no cumple con los requisitos mínimos necesarios de las buenas prácticas de certificación[62]https://cabforum.org/. A continuación se muestra en detalle la estructura completa de un certificado real, en el que la información de puntos de consulta de revocación descentralizada convive con los mecanismos tradicionales.
Version: 2 (v3)
SerialNumber: 161622362496637328561239031025230663875 (hex: 0x799755b2edcbf3e576674490214fd0c3, bits: 128)
Signature:
algo: 1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
params: NULL
Issuer:
2.5.4.3 (commonName,CN): ESFIRMA DEV AAPP (type: utf8String)
Subject:
2.5.4.97 (organizationIdentifier): VATES-TEST (type: utf8String)
2.5.4.6 (countryName,C): ES (type: printableString)
2.5.4.7 (localityName,L): ZARAGOZA (type: utf8String)
2.5.4.10 (organizationName): PRUEBA-TEST (type: utf8String)
2.5.4.5 (serialNumber,SN): TEST (type: printableString)
2.5.4.15 (businessCategory): Government Entity (type: utf8String)
1.3.6.1.4.1.311.60.2.1.3 (jurisdictionOfIncorporationCountryName): ES (type: printableString)
Validity:
Duration: 1 year 25 days
NotBefore: 2021-02-12T12:16:32Z
NotAfter: 2022-03-09T12:16:32Z
SubjectPublicKeyInfo:
Algorithm:
algo: 1.2.840.113549.1.1.1 (RSA)
params: NULL
PublicKey:
[...]
Key length: 2048 (0x800)
[...]
Extensions:
2.5.29.32 (Certificate policies)
Policies:
2.16.724.1.3.5.5.2 (MPR SEDE ELECTRONICA (Nivel Medio,Sustancial))
0.4.0.194112.1.4 (QCP-w: certificate policy for European Union (EU) qualified website authentication certificates )
1.3.6.1.4.1.47281.1.4.2 (esFIRMA Sede electrónica AAPP - MEDIO en Software - EV):
1.3.6.1.5.5.7.2.1 (CPS)
URI: https://www-esfirma.g3stiona.com/doc-pki/ (type: IA5String)
1.3.6.1.5.5.7.2.2 (User Notice)
ExplicitText: Certificado cualificado de sede electrónica de PRUEBA-TEST nivel medio. Consulte https://www-esfirma.g3stiona.com/doc-pki/ (type: utf8String)
2.23.140.1.1 (Extended Validation (EV) guidelines certificate policy)
2.5.29.14 (Subject key identifier)
Identifier: 03:3f:07:0b:b8:46:69:db:a8:01:97:c8:e9:a5:8c:6e:
3f:41:5a:12
2.5.29.35 (Authority key identifier)
Identifier: f4:76:84:70:6c:94:96:9a:f9:d8:26:74:94:ec:2e:d9:
34:5a:db:35
2.5.29.19 (Basic constraints)
None
2.5.29.15 (Key usage):
Critical
0 (DigitalSignature)
2 (KeyEncipherment)
2.5.29.37 (Extended key usage)
1.3.6.1.5.5.7.3.1 (serverAuth)
2.5.29.31 (Revocation List distribution points):
DistributionPoint
Name
FullName
[0] uri: http://crls1-esfirma.g3stiona.com/acaapp/acaapp.crl (type: IA5String)
DistributionPoint
Name
FullName
[0] uri: http://crls2-esfirma.g3stiona.com/acaapp/acaapp.crl (type: IA5String)
1.3.6.1.5.5.7.1.1 (Authority Information Access):
AccessDescription:
Method: 1.3.6.1.5.5.7.48.1 (ocsp)
Location
uri: http://ocsp1-esfirma.g3stiona.com/acaapp/ (type: IA5String)
AccessDescription:
Method: 1.3.6.1.5.5.7.48.1 (ocsp)
Location
uri: http://ocsp2-esfirma.g3stiona.com/acaapp/ (type: IA5String)
AccessDescription:
Method: 1.3.6.1.5.5.7.48.2 (caIssuers)
Location
uri: http://www-esfirma.g3stiona.com/doc-pki/acaapp.crt (type: IA5String)
1.3.6.1.4.1.47281.555.1.1 (DCRL - Decentralized Certificate Revocation Log)
uri: dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645 (type: IA5String)
2.5.29.17 (Subject alternative name)
DNSName: good2.testing.esfirma.com (type: IA5String)
1.3.6.1.5.5.7.1.3 (QcStatements):
0.4.0.1862.1.1 (QcCompliance)
0.4.0.1862.1.6 (QcType)
0.4.0.1862.1.6.3 (web)
0.4.0.1862.1.3 (QcRetentionPeriod)
Years: 15 (0xf)
0.4.0.1862.1.5 (QcPDS):
Location:
lang: en (type: PrintableString)
url: https://www-esfirma.g3stiona.com/doc-pki/PDS/SE2-MEDIO-SOFT-EN/ (type: IA5String)
Location:
lang: es (type: PrintableString)
url: https://www-esfirma.g3stiona.com/doc-pki/PDS/SE2-MEDIO-SOFT-ES/ (type: IA5String)
1.3.6.1.5.5.7.11.2 (id-qcs-pkixQCSyntax-v2)
keyIdentifier: 0.4.0.194121.1.2 (Id-etsi-qcs-SemanticsId-Legal)
2.23.140.3.1 (CABForum OrganizationIdentifier):
SchemeIdentifier: VAT (type: printableString)
Country: ES (type: printableString)
Reference: TEST (type: utf8String))
[...]
Las conclusiones
La confianza es la clave. Para el sistema mostrado en este artículo confiamos en la lista de certificados raíz que viene preconfigurada con el navegador, en los servidores DNS que tenemos configurados para resolver la dirección IP de un nombre de dominio. Así como los nodos iniciales que nos permiten arrancar la red de Ethereum.
En general es mejor evitar sistemas centralizados que son más vulnerables que sus equivalentes descentralizados. Las nuevas tecnologías descentralizadas reemplazarán inevitablemente poco a poco las viejas estructuras.
¡La redescentralización ha comenzado[63]Probablemente hasta hoy no ha existido una verdadera descentralización. Así que ¡La descentralización ha comenzado!!
Referencias[+]
↑1 | Mejor sería usar un exchange descentralizado. |
---|---|
↑2 | HTTP (Hypertext Transfer Protocol) son unas reglas que permiten realizar peticiones de documentos y recursos a otro ordenador mediante TCP. Las respuestas pueden contener enlaces a otros documentos y recursos creando una red de información (https://es.wikipedia.org/wiki/Protocolo_de_transferencia_de_hipertexto). HTTPS (https://es.wikipedia.org/wiki/Protocolo_seguro_de_transferencia_de_hipertexto) por tanto es el protocolo HTTP sobre TLS/SSL (https://es.wikipedia.org/wiki/Seguridad_de_la_capa_de_transporte) |
↑3 | https://es.wikipedia.org/wiki/HTTP_Strict_Transport_Security |
↑4 | https://es.wikipedia.org/wiki/Cifrado_(criptograf%C3%ADa) también se le llama encriptar, pero es más macabro |
↑5 | https://es.wikipedia.org/wiki/Criptograf%C3%ADa_sim%C3%A9trica |
↑6 | Una de los algorotmos más utilizado es Diffie-Hellman (https://simple.wikipedia.org/wiki/Diffie-Hellman_key_exchange) |
↑7 | En matemáticas hay varias operaciones equivalentes a mezclar los colores. Una habitual es la exponenciación discreta (https://es.wikipedia.org/wiki/Logaritmo_discreto). |
↑8 | https://es.wikipedia.org/wiki/Ataque_de_intermediario |
↑9 | La criptografía asimétrica ha supuesto una auténtica revolución en la sociedad. Sobre ella se ha construido el mundo digital que conocemos (https://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica) |
↑10 | https://es.wikipedia.org/wiki/Huella_digital_de_clave_p%C3%BAblica |
↑11 | Además no se puede deducir el mensaje original a partir de la huella |
↑12 | Más o menos probablemente dependiendo de en qué soporte (SmartCard, sistema centralizado, token de software) resida la clave privada, entre otras cosas |
↑13 | El objeto de cifrado suele tener más información para evitar otro tipo de ataques. |
↑14 | También existen certificados de autenticación web que incluyen el dueño legal de las claves privadas, el nombre de la organización lo que complica un poco la verificación de los datos a la hora de emitir un certificado. Hay que destacar en este punto que el certificado identifica a un dominio, pero esto no garantiza que esté accediendo al sitio correcto. El DNS, otra infraestructura con muchos años, tiene sus propios problemas… |
↑15 | Existen otros modelos de certificación, Web of Trust, SPKI, DPKI, Blockchain PKI… |
↑16 | Estrictamente hablando la verificación de los datos la realiza una Autoridad de Registro (AR) pero lo vemos un poco más adelante |
↑17 | https://es.wikipedia.org/wiki/Cadena_de_confianza |
↑18 | https://www.usenix.org/legacy/publications/library/proceedings/sec96/full_papers/ellison/index.html |
↑19 | https://es.wikipedia.org/wiki/Auto-Identidad_Soberana |
↑20 | Unas 650 directa o indirectamente actualmente, https://www.eff.org/observatory |
↑21 | También las llaman entidades emisoras |
↑22 | https://arstechnica.com/information-technology/2017/03/google-takes-symantec-to-the-woodshed-for-mis-issuing-30000-https-certs/ |
↑23 | https://www.wired.com/2011/09/diginotar-bankruptcy/ |
↑24 | https://www.eff.org/deeplinks/2011/05/syrian-man-middle-against-facebook |
↑25 | https://www.eff.org/es/deeplinks/2011/03/iranian-hackers-obtain-fraudulent-https https://www.theregister.com/2012/02/09/tustwave_disavows_mitm_digital_cert/ https://docs.microsoft.com/en-us/security-updates/securitybulletins/2001/ms01-017 https://www.enisa.europa.eu/media/news-items/operation-black-tulip/ |
↑26 | Es el eslabón más débil. Comprometer una AC supone comprometer todo el sistema |
↑27 | Tecnología con 40 años de existencia… |
↑28 | El tiempo, el reloj es una de las primeras causas de ataques informáticos. Mantener el reloj del sistema sincronizado es todo un reto. Ver NTP, sdwdate |
↑29 | https://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf |
↑30 | https://blog.cryptographyengineering.com/2012/02/28/how-to-fix-internet/ |
↑31 | https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning |
↑32 | https://certificate.transparency.dev/ |
↑33 | Estos registros acabarán utilizando la blockchain en un futuro próximo. |
↑34 | Añadir estos servicios de verificación es muy cuestionable y posiblemente no sea una buena solución. Reducir el tiempo de validez de un certificado es la única solución. Un certificado será válido durante su tiempo de validez y sí este periodo no es aceptable para el receptor del certificado sería mejor que no confiase en él. Sin más verificaciones. |
↑35 | Pese a que se suelen utilizar servicios de alta disponibilidad |
↑36 | “soft-fails” |
↑37 | https://github.com/agl/crlset-tools |
↑38 | Y todavía más siguiendo las recomendaciones de algunas normas que quieren mantener los certificados revocados en las listas incluso cuando estos han expirado. Las listas incrementales sólo complican más las cosas. Para mitigarlo se proponen variaciones sobre el mecanismo como las CRL Delta o las CRL Particionadas, creando, en general, problemas de interoperabilidad. |
↑39 | No estoy muy seguro de por qué razón en este momento el servicio no fue simplemente mandar una lista con los certificados de los que se quiere información y se creó una nueva estructura completamente distinta… |
↑40 | OCSP Stapling |
↑41 | smartCert,EthIKS,COINIKS,CertCoint,BlockPKI,Gossip,PoliCert,PKISN… |
↑42 | Quiere decir que sólo se pueden añadir nuevos datos, no modificar los anteriores, que son inmutables. |
↑43 | https://geth.ethereum.org/docs/getting-started |
↑44 | 1 ether = 10^18 Wei (un trillón) |
↑45 | https://ethereum.org/es/developers/docs/evm/ |
↑46 | https://es.wikipedia.org/wiki/Solidity |
↑47 | Puede calcularse de otra forma siempre pero es habitual que sea derivado de la clave pública |
↑48 | https://www.trufflesuite.com/ |
↑49 | https://remix-project.org/ |
↑50 | También puedes instalarlo localmente: https://github.com/ethereum/remix-ide |
↑51 | https://www.nasa.gov/perseverance |
↑52 | https://medium.com/firmonetwork/3-famous-smart-contract-hacks-you-should-know-dffa6b934750 |
↑53 | https://openzeppelin.com/ |
↑54 | https://es.wikipedia.org/wiki/Error_de_software#Casos_notables , https://es.wikipedia.org/wiki/Ariane_5#Falla_del_ARIANE_5G_de_1996 |
↑55 | https://arxiv.org/pdf/1806.01143.pdf |
↑56 | En el 2003 dos líneas de código fueron eliminadas, del proyecto OpenSSL, tras la sugerencia de dos herramientas de análisis estático de código (valgrind y purify). Esto provocó que la entropía necesaria para generar claves fuera mermada acabando en un grave agujero de seguridad. https://en.wikinews.org/wiki/Predictable_random_number_generator_discovered_in_the_Debian_version_of_OpenSSL |
↑57 | https://es.wikipedia.org/wiki/ASN.1 |
↑58 | https://es.wikipedia.org/wiki/Identificador_de_recursos_uniforme |
↑59 | https://github.com/antik10ud/xray509 es un proyecto para visualizar certificados |
↑60 | https://github.com/web3j/web3j |
↑61 | Los contratos inteligentes de Ethereum son Turing-completos. Para evitar bucles infinitos y otros problemas, la ejecución de los métodos del contrato requiere un límite de gas, que una forma de medir la cantidad de cómputo máxima necesaria. El gas se paga a un determinado precio variable. (https://ethgas.io/) |
↑62 | https://cabforum.org/ |
↑63 | Probablemente hasta hoy no ha existido una verdadera descentralización. Así que ¡La descentralización ha comenzado! |