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.
Quan accedim a un lloc web a través del nostre navegador, esperem que la informació que intercanviem amb aquest lloc sigui confidencial i integra. No volem que tercers vegin les nostres credencials d’accés al banc o que algú sàpiga quantes criptomonedes estem comprant en el nostre exchange favorit. Per això afegim la “s” de segur al “http” cada vegada que introduïm una adreça web en la barra d’adreces del nostre navegador. De hecho, hoy en día se suele añadir de forma automática, gairebé sempre.
Per aconseguir aquesta comunicació segura la informació intercanviada es fa inintel·ligible per a tot aquell que no tingui la clau. A això se li diu xifrar lla informació. Tant les peticions d’informació que fa el navegador al lloc web com la informació de resposta que el lloc web envia al navegador de tornada estan xifrades.
La clau secreta és acordada entre les dues parts, navegador i lloc web. Aquesta clau s’anomena clau de sessió, perquè es renegociarà entre les parts cada poc temps. Si imaginem que les claus són colors, la informació xifrada pel servidor amb un color només pot ser desxifrada pel navegador utilitzant aquest mateix color i cap altre. Un adversari, algú escoltant, només pot veure la informació intercanviada si coneix el color utilitzat o és capaç de deduir-lo. Aquest tipus de xifratge que utilitza una sola clau es diu simètric. És molt adequat perquè el xifratge simètric és molt ràpid i segur. A més ens permet, amb certes cauteles, xifrar grans quantitats d’informació.
Per aconseguir establir una clau secreta compartida en presència de tercers, les dues parts implicades utilitzen un protocol, unes regles d’intercanvi de clau. Continuant amb l’analogia dels colors, aquest protocol es basa en la idea que és fàcil barrejar dos colors però molt difícil separar-los després. Les dues parts es posen d’acord públicament en un color comú inicial. Cadascú barreja aquest color comú amb el seu propi color secret per obtenir un color barrejat que enviarà a l’altra part. Finalment, cada part barrejarà el color rebut amb el seu color secret i així obté un color compartit igual que el de l’altra part. La figura següent ho explica molt bé:
En resum, ambdues parts barregen el color comú amb els dos colors secrets, un de cada part.
Aquest protocol permet acordar l’ús d’una clau compartida de manera segura. Però en la seva versió bàsica o anònima, no garanteix amb qui estic intercanviant informació. És a dir, no és autenticat. No es comprova que les parts implicades siguin qui diuen ser. Això permetria a un atacant col·locar-se entre les dues parts sense que cap d’elles se n’adoni, creient ambdues que només estan elles dues en la comunicació. Això es diu atac d’intermediar
o d’home al mig.
Una solució per saber amb qui estem parlant és que els missatges enviats estiguin signats digitalment.
La signatura digital és una de les aplicacions de la criptografia asimètrica.
En lloc d’utilitzar la mateixa clau per xifrar i desxifrar una informació, la criptografia asimètrica n’utilitza dues. És a dir, tenim una parella de claus vinculades de tal manera que el que xifra una de les claus només pot ser desxifrat per l’altra i cap altra. La clau que s’utilitza per xifrar informació és una clau secreta, privada. L’altra és la clau pública, la podem lliurar a tothom. Amb la clau pública que pot desxifrar la informació que he xifrat amb la clau privada.
Cal recalcar que en realitat estem enviant dos objectes. D’una banda, el missatge públic i, per una altra, una signatura d’aquest missatge. Si canvio el missatge, la signatura no serà vàlida. La signatura és el missatge xifrat amb la clau privada. Però, la criptografia de clau asimètrica és lenta, molt lenta, i no pot xifrar missatges gaire llargs. Per això el que es xifra, el que se signa, és una representació del missatge, anomenada empremta digital. Aquesta representació és un altre missatge d’una mida fixa més petita, però prou gran per evitar col·lisions. D’aquesta manera, tot missatge, de qualsevol mida, pot representar-se per aquesta empremta digital. El canvi d’una sola lletra en el missatge canviarà completament la seva empremta.
Això vol dir que aquí no hi ha confidencialitat de cap tipus. Tothom pot desxifrar els meus missatges xifrats. Només han d’utilitzar la clau pública, que és pública. Té sentit, ja que es tracta d’una signatura. El que sí que garanteix
és que només jo he pogut xifrar aquest missatge, com a controlador exclusiu d’aquesta clau secreta. I és el que equival a una signatura.
En resum, per signar un missatge calculem la seva empremta digital i la xifrem, i obtenim un missatge que anomenarem signatura. Per verificar una signatura la desxifrem i verifiquem que el valor obtingut és l’empremta digital del missatge.
Els navegadors han d’obtenir les claus públiques de les web a les quals accedim i estar segurs que són autèntiques per aconseguir establir una comunicació segura. Quan no podem verificar si les claus públiques corresponen al web a què estem intentant accedir el nostre trànsit podria ser interceptat i manipulat per un tercer sense adonar-nos-en.
Un certificat digital vincula una clau pública amb una identitat i altres dades. En el cas d’un certificat d’autenticació web, la identitat es refereix al nom de domini. A més els certificats digitals inclouen la data des de la qual és vàlid, que sol ser la data d’emissió, i la data fins que serà vàlid.
Totes les dades que surten juntes en un certificat són signades digitalment per una autoritat de certificació (AC), també anomenada entitat emissora. L’AC s’encarrega de verificar la validesa de totes aquestes dades incloses al certificat abans d’emetre’l, abans de signar-lo.
L’AC signa digitalment el certificat utilitzant el seu propi certificat. Com que tot certificat és emès per una AC es crea una cadena de confiança d’autoritats de certificació. Aquesta cadena acaba quan una AC emet un certificat que es verifica a si mateix i que es diu certificat arrel.
Establir la identitat d’un certificat sense una autoritat de certificació es un viejo anhelo. Hasta hoy no lo hemos logrado, pero estamos cerca.
Tots els navegadors venen preconfigurats amb una sèrie d’AC que permeten verificar i acceptar certificats d’autenticació de llocs web emesos per aquestes AC. Cada navegador té el seu propi procediment per afegir o eliminar les AC que venen preconfigurades. Un certificat emès per una AC pot ser acceptat en un navegador i no en un altre, i això sol crear problemes estranys. Al final, un grapat de persones responsables de cada navegador decideixen quines AC són incloses en aquest “petit” llistat d’AC confiables que garanteixen la nostra seguretat en les comunicacions. Sempre ha estat així al món humà.
Les AC poden emetre certificats per a qualsevol domini a la seva discreció, com va fer Symantec emetent certificat “de prova” amb el domini de google. Aquests certificats podrien haver estat utilitzats per llançar atacs de phising molt efectius.
Amb el poder que tenen les AC, les fa objectius molt desitjables per als furons, com ho va ser DigiNotar. También los gobiernos pueden abusar de su poder como hizo Siria intentando un ataque de intermediario con FaceBook.
Una AC pot ser deshonesta, o pot estar compromesa d’alguna manera. Sigui volent o sense voler, una AC compromesa pot emetre certificats amb claus públiques falses, per a qualsevol domini. Tot navegador que confiï en aquesta AC maliciosa acceptarà sense parpellejar els certificats per ella emesos. Un atacant pot falsificar certificats per a qualsevol web que desitgi i no hi haurà manera de diferenciar-los de certificats autèntics.
La infraestructura de clau pública
són les polítiques i procediments, el programari, el maquinari, que es necessiten per gestionar certificats digitals. Gestionar vol dir com emetre’ls, utilitzar-los, emmagatzemar-los, revocar-los, eliminar-los…
Algunes de les funcions d’una AC poden ser delegades. Per exemple, l’AC delega en l’autoritat de registre (AR) la verificació de les dades d’identitat que hi ha en un certificat.
Les entitats de validació (AV) proporcionen els serveis necessaris per comprovar que un certificat continua sent vàlid en un moment determinat. El certificat té entre les seves dades un període de validesa. No cal una AV per verificar si el certificat és dins d’aquell període, més enllà de tenir un rellotge correctament sincronitzat. Però sí en els casos en els quals el certificat o alguna de les seves dades deixen de ser vàlids per alguna altra raó.
El model d’infraestructura pública és fràgil. 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, que no han funcionado. Actualmente se usa un registro público transparente y verificable de la emisión de certificados de cada AC per reduir els certificats emesos per error o malintencionadament.
El temps de vida d’un certificat és relativament llarg, en l’ordre de mesos. Alguna dada del certificat pot deixar de ser correcta, es pot perdre el control de la clau privada associada al certificat, l’entitat emissora pot haver estat compromesa, s’ha perdut… Però el certificat és un objecte immutable. Per això s’estableixen diferents mecanismes que permeten consultar l’estat del certificat. Almenys l’estat que tenia fa poc temps, en l’ordre d’hores.
Un certificat està “revocat” quan un perd la seva validesa per altres causes que no siguin l’expiració.
Els serveis per verificar l’estat de revocació d’un certificat els proporciona l’AV i els mitjans per accedir-hi solen anar al mateix certificat. Aquests serveis són un altre taló d’Aquil·les de la infraestructura de clau pública.
Un navegador no pot estar segur que els servidors de l’AV seran accessibles per verificar l’estat d’un certificat. Per exemple, un portal captiu només permet autenticar-se en una adreça HTTPS però bloqueja el trànsit a qualsevol altra adreça, incloent els serveis de consulta de revocació del certificat. Si el navegador no accepta el certificat, quan no pugui verificar el seu estat no es podrà accedir al lloc web, i deixarà de funcionar. D’altra banda, un tall, per petit que sigui, dels serveis de consulta d’estat implica un punt únic de fallada.
Per això, molts navegadors consideren els errors de xarxa a l’hora de consultar l’estat de revocació d’un certificat com a fallades que simplement són ignorades. A més, els costos de la verificació són més temps de connexió, pàgines més lentes i possibles problemes de privacitat perquè les AV poden registrar els dominis consultats i des de quina ip… Per això, alguns navegadors utilitzen un mecanisme que envia les llistes de certificats revocats de totes l’AC a cada navegador, que complica lleugerament les coses a un atacant.
Un dels primers serveis per a la consulta de l’estat de revocació d’un certificat va ser utilitzar una llista (CRL). En aquesta llista hi ha l’identificador del certificat amb un estat de revocació. Si el certificat no surt a la llista, serà vàlid. Els certificats solen incloure un o diversos serveis des dels quals descarregar aquestes llistes.
Les llistes s’actualitzen cada cert temps per reflectir els canvis. Un dels problemes amb aquestes llistes és que creixen de manera desmesurada amb el temps, poden ser problemàtiques respecte de la privacitat de dades, o simplement no estan prou actualitzades…
Aquest petit caos amb les llistes de revocació va desembocar en la creació d’un nou servei que permetés comprovar l’estat d’un certificat en concret directament (OCSP).E
En lloc de descarregar una llista cada cert temps, els navegadors poden fer les consultes cada vegada i només per al certificat que estan utilitzant. Però això va crear una dependència molt més gran entre l’AV i el navegador. Els atacs de denegació de servei són més fàcils. La disponibilitat del servei es torna més crítica. La privacitat empitjora…
Per alleujar algun d’aquests problemes s’estableixen protocols per enviar l’estat de revocació juntament amb el certificat del lloc web però creen els seus propis problemes.
Cada dia surten noves propostes per a la consulta de l’estat de revocació d’un certificat, com a solució específica o englobada en una solució més general.
La cadena de blocs (blockchain) és un registre públic i descentralitzat de dades que s’actualitza, només afegint entrades en forma de transaccions, mitjançant el consens de tots els participants. Les dades s’emmagatzemen de manera redundant en molts llocs. Bitcoin, el precursor de la blockchain, permet mantenir un registre públic dels intercanvis de valor entre els participants. És molt difícil de censurar, ja que no té una entitat central que el controli. Serà molt difícil prohibir-lo sense que es consideri un atac a la mateixa llibertat d’expressió i el dret a comunicar-nos. Ethereum, per la seva banda, fa ús d’una blockchain per mantenir un consens no només sobre la informació, sinó sobre petites aplicacions que manipulen aquesta informació, i es converteix en una espècie d’ordinador global públic compartit. Ethereum anomena aquestes petites aplicacions contractes intel·ligents.
LLa blockchain proporciona nous casos d’ús que prèviament no es podien resoldre de manera satisfactòria Proporciona immutabilitat, una vegada escrit un registre en un bloc no es pot alterar perquè requeriria alterar tots els blocs anteriors que requereixen el consens de tots els participants. És un sistema descentralitzat que evita molts atacs com la denegació de servei. És transparent, la blockchain és visible públicament. És ràpida i més barata, en relació amb sistemes equivalents amb les mateixes garanties.
Explorarem les possibilitats d’utilitzar blockchain com a registre de l’estat de revocació dels certificats emesos per una AC. L’anomenarem Decentralized Certificate Revocation List (DCRL).
Definirem i desplegarem un contracte intel·ligent d’Ethereum per gestionar la llista. Definirem una nova extensió del certificat que inclogui l’adreça del contracte intel·ligent. Crearem uns certificats d’exemple i implementarem les eines per revocar un certificat i per consultar-ne l’estat.
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.
Un node pot llançar-se amb diferents maneres. El mode complet (full) emmagatzema totes les dades de la blockchain, participa en la validació de blocs, verifica blocs i estats… El mode lleuger només valida les dades de les capçaleres dels blocs i s’utilitza en dispositius embeguts o de pocs recursos.
Nosaltres utilitzarem el mode “fast”, que només utilitza l’estat més recent de la blockchain.
Descarreguem el client del web d’Ethereum. Deixem per a la reflexió com estarem segurs que hem accedit al web autèntic i que hem descarregat un paquet legítim.
https://geth.ethereum.org/downloads/
Per exemple, utilitzant wget per a una distribució linux 64bits
wget https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.25-e7872729.tar.gz
Descomprimim el paquet i accedim al directori
tar xvf geth-linux-amd64-1.9.25-e7872729.tar.gz
cd geth-linux-amd64-1.9.25-e7872729
i llancem el node utilitzant aquesta línia d’ordres
$ geth --goerli --syncmode "light" --http --
http.corsdomain="https://remix.ethereum.org" --allow-insecure-unlock
Alguns dels paràmetres importants de geth
–http | Activa el servei JSON-RPC, que permet a altres aplicacions utilitzar el node via API |
–http.corsdomain | Només es permetrà l’accés a l’API des de “https://remix.ethereum.org” que serà l’entorn amb què despleguem el contracte intel·ligent |
–goerli | Utilitzarem la xarxa de proves Görli. Ethereum disposa de diverses xarxes de proves i una de producció. Görli és una xarxa proof-of-authority que funciona amb clients Parity, Geth i d’altres |
–syncmode | Utilitzarem el mode de sincronització “light”, per defecte és “fast” |
–datadir | El directori on s’emmagatzemaran les dades de la blockchain. Ocuparà uns 12GB si utilitzem un node “fast” i 500MB si utilitzem un node “light”. Si no ho especifiquem, utilitzarà el directori per defecte que és ~/.ethereum/goerli |
–cache | Augmentar a 2048 la memòria millora el rendiment en cas de sincronització “fast” |
–allow-insecure-unlock | Permet desbloquejar un moneder alhora que s’utilitza l’API, la qual cosa no és recomanable fora de desenvolupament. |
console | Llança una consola JavaScript per interactuar amb el node |
El mode “light” és experimental, però prou estable com per a la nostra comesa.
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
En llançar el node començarà a sincronitzar-se amb la xarxa automàticament. Recorda que aquesta sincronització trigarà diverses hores en el cas que el mode sigui “fast”.
Per interactuar amb el node des d’una altra terminal utilitzem l’ordre attach:
$ geth --goerli attach
Welcome to the Geth JavaScript console!
[..]
To exit, press ctrl-d
En introduir a la consola l’ordre eth.syncing obtindrem l’estat de sincronització del node o false si està completament sincronitzat. eth és un objecte que permet interactuar amb els contractes intel·ligents i la mateixa blockchain.
> eth.syncing
{
currentBlock: 213539,
highestBlock: 4264547,
knownStates: 511823,
pulledStates: 502449,
startingBlock: 0
}
mb l’ordre eth.blockNumber obtindrem l’últim bloc processat pel nostre node.
> eth.blockNumber
4269342
Per enviar transaccions a la blockchain necessitem unes credencials a més del node. Les credencials són una clau pública i una altra de privada. A partir de la clau pública obtindrem un número de compte o adreça (address). Utilitzant missatges signats digitalment amb la nostra clau privada enviem operacions en forma de transaccions a la blockchain.
El lloc on desem aquestes claus es diu cartera o moneder (wallet) i té associat un balanç, uns ether, que ens permetran enviar les transaccions a la xarxa. Crear un nou compte no requereix cap tipus d’autorització. Ethereum és una xarxa no permissionada.
No tenim cap compte en el nostre node local. Per afegir-ne un utilitzem l’objecte personal que s’encarrega d’interactuar amb els comptes del node:
> personal.newAccount()
Establim una contrasenya, que podem deixar en blanc per a les proves. Per obtenir els comptes que tenim escrivim:
> personal.listAccounts
["0x673ce1bda1ca6a7d969b8f44e44d78ce9ef11691"]
encara que també podem utilitzar eth.accounts, més habitual. El balanç del compte resideix en la blockchain, no en el compte i, per tant, per obtenir-lo utilitzem mètode getBalance de l’objecte eth, que ens donarà els Wei en el compte.
> eth.getBalance(eth.accounts[0])
0
Per afegir fons accedim a algun dels serveis gratuïts de subministrament per a la xarxa Görli. Introduirem la nostra adreça i amablement ens transferiran una petita quantitat d’ethers. En producció utilitzarem algun exchange per adquirir ethers a canvi d’euros o dòlars.
Per exemple, podem accedir a https://goerli-faucet.slock.it/
En uns instants tindrem els fons disponibles en el nostre compte.
Ethereum executar petites aplicacions mitjançant una màquina virtual 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. És un llenguatge orientat a objectes amb tipus específics, modificadors de funcions per crear precondicions, gestió d’esdeveniments…
El nostre contracte intel·ligent és molt senzill. Conté la llista de certificats que hagin estat revocats. Si surten a la llista, han estat revocats, sense més informació inicial. Cada AC gestionarà el contracte intel·ligent que gestiona la llista
Els certificats es localitzen mitjançant el seu identificador de subjecte (Subject Key Identifier, SKID). L’SKID és una extensió dels certificats que es calcula a partir de la seva clau 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 codi del contracte intel·ligent té un mapa que associa un enter de 256bits amb un valor booleà. Té dues funcions, una per a la consulta de l’estat d’un certificat i una altra per revocar un certificat, ambdós identificats mitjançant el SKID. El mètode revoke només pot ser cridat pel propietari del contracte.
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];
}
}
Per desenvolupar contractes intel·ligents podem utilitzar entorns com ara truffle, que nos permite tener un ciclo de desarrollo sano. En este artículo usaremos directamente un editor online llamado Remix, que ens permetrà compilar, executar, analitzar i desplegar el contracte a través del nostre node local.
Accedirem a https://remix.ethereum.org/?#gist=505a93da7b10ed3438a0dcc68832b337 donde veremos el entorno Remix como se muestra a continuación, amb el contracte DCRL.sol precarregat des de gist.
A l’esquerra podem accedir a l’arbre del projecte, el compilador, l’accés al node per enviar transaccions i contractes i el gestor de complements. En el centre tenim el panell principal i sota, una terminal.
Podem editar el contracte, cada vegada que el desem s’autocompilarà mostrant els possibles errors de sintaxi.
Per desplegar el contracte accedirem a la pestanya “Deploy & Run Transactions”. Establirem com a entorn el nostre node local. Per a això seleccionem “Web3 Provider” a Environment. Deixarem el “Web3 Provider Endpoint” en el seu valor per defecte http://127.0.0.1:8545”. Després d’això sortiran els comptes del nostre node juntament amb el seu balanç a la secció “Account”. Seleccionarem el que tingui fons disponibles si en tenim més d’un.
Des de la consola del nostre node local desbloquejarem el compte per poder signar la transacció utilitzant el mètode unlockAccount de personal:
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x673ce1bda1ca6a7d969b8f44e44d78ce9ef11691
Passphrase:
true
A continuació premerem el botó “Deploy” des de l’entorn.
Desplegar un contracte és enviar una transacció a la xarxa Ethereum a través del nostre node local. El deploy no és instantani, la xarxa ha d’afegir la transacció a un bloc i arribar a un consens sobre la seva validesa. Una vegada arribat a l’acord, el nostre contracte està disponible globalment en una adreça.
Podem veure l’estat de les transaccions utilitzant un explorador de transaccions. Podem obtenir directament una url d’accés a la consola de l’entorn:
https://goerli.etherscan.io/tx/…
Una vegada desplegat, podem interactuar amb el contracte directament des del mateix entorn de desenvolupament, on sortiran els diferents mètodes disponibles al contracte.
Si introduïm una id en el mètode “has” i premem el botó del mètode, llançarem l’la crida i obtindrem el resultat esperat en el camp “decoded output” de la consola de l’entorn:
{
"0": "bool: false"
}
Si ara utilitzem el mètode revoke, després de desbloquejar el compte, amb un paràmetre i consultem de nou el seu estat amb el mètode has, obtindrem true indicant que el certificat amb aquest SKID ha estat revocat.
Com a exercici demostrar que un altre compte no pot actualitzar la llista, crear usuari, etc.
Programar correctament un contracte intel·ligent és una feina especialment delicada. No només pels bugs que puguin tenir sinó pel seu propi disseny. El programari ha salvat moltes vegades la situació. Si la 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 o fer millores.
Un contracte intel·ligent és “actualitzable” creant un nou contracte i transferint l’estat del vell contracte al nou. Però migrar l’estat pot ser car, l’adreça del contracte canviarà i el període de temps en el qual el vell i nou contracte coexisteixin és un gran problema.
L’alternativa és utilitzar un contracte (servidor intermediari o representant) per emmagatzemar l’estat i redirigir les crides a un altre contracte anomenat implementació que emmagatzema la lògica de negoci. D’aquesta manera, podem actualitzar la lògica de negoci sense haver de realitzar migracions més enllà d’indicar al servidor intermediari quina lògica utilitzar.
Projectes com OpenZeppelin
proporcionen un framework per simplificar la programació de contractes intel·ligents actualitzables.
Però cal advertir que reduir l’esforç de programar adequadament perquè el programari es pot actualitzar és un error de conseqüències molt greus. Y en el ámbito de los contratos inteligentes son habituales los robos o bloqueos irreversibles de fondos.
Un contracte intel·ligent ha d’utilitzar totes les eines al seu abast per garantir la seva seguretat. Incloent auditories, anàlisis estàtiques i dinàmiques de codi, tests…
Des del mateix entorn Remix podem utilitzar plugins que proporcionen anàlisis bàsiques de seguretat i estil. Per exemple, utilitzant Solint i Solidity Static Analysis obtenim els informes següents:
ls informes obtinguts són només això, informes amb suggeriments o aspectes a revisar. No seria la primera vegada que fer cas a cegues a aquestes anàlisis provoca un problema molt seriós. Però tampoc no s’han d’ignorar els advertiments a la lleugera. Discutir cada advertiment amb altres persones competents i amb calma sol ser el més recomanable.
Incorporarem l’adreça del contracte intel·ligent que acabem de desplegar als certificats mitjançant la definició d’una nova extensió.
L’estàndard ASN.1 s’utilitza per a la descripció d’estructures de dades de manera independent a la màquina. L’estructura dels certificats se sol expressar utilitzant aquesta sintaxi. La nostra extensió serà la següent:
DCRL EXTENSION ::= {
SYNTAX DCRLURIList
IDENTIFIED BY id-dcrl }
DCRLURIList ::= SEQUENCE OF DCRLURI
DCRLURI ::= IA5String
Els OIDS són una seqüència de números separats per punt, jeràrquics que permeten identificar objectes. En aquesta extensió utilitzarem:
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 corresponen a la taula següent
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) |
L’extensió contindrà una llista, una seqüència, d’identificadors de recursos uniforme (URI).
Cada URI definirà l’accés a un servei de consulta d’una blockchain.
Definirem l’URI d’accés al contracte intel·ligent DCRL de la xarxa com
dcrl:ethereum:
En el nostre cas, l’URI de consulta per al contracte intel·ligent que acabem de desplegar serà:
dcrl:ethereum:0xd807991602EC9269e233e54188a5b9A6Ed904645
Per poder visualitzar l’extensió DCRL d’un certificat fàcilment afegirem la lògica al projecte XRAY-509. Afegim el processador de l’extensió 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;
}
}
fegirem el processament a la llista d’extensions conegudes en el mètode registerExtensions de la classe Context.
registerExtension("1.3.6.1.4.1.47281.555.1.1",new DCRLProc());
Com a exercici, fer el testing adequat a aquesta nova funcionalitat
Emetre un certificat digital consisteix a generar una parella de claus, crear una sol·licitud de signatura de certificat (CSR) i enviar el CSR a l’AC perquè generi el certificat.
Llançarem la nostra pròpia AC de proves basada en OpenSSL. Per a això crearem un certificat arrel.
$ 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 []:
Utilitzant l’eina de visualització podem veure l’estructura detallada del certificat generat:
$ 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
[...]
Preparem la configuració de la CA per emetre certificats amb suport DCRL.
Creem el fitxer 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
i el fitxer cert.extensions.conf en el qual definirem l’extensió DCRL amb l’URI del nostre contracte intel·ligent.
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
Generem les claus i el CSR per al certificat final. Per a això afegirem un fitxer cert.conf amb les dades que ens agradaria que surtin al certificat:
[ 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
Creem el CSR per enviar-lo a l’AC
$ openssl req -new -out cert.csr -config cert.conf
L’AC verificarà la informació continguda en el CSR, validarà la identitat del sol·licitant i emetrà un certificat.
$ openssl ca -config ca.conf -out cert.crt -extfile cert.extensions.conf -in cert.csr
El nou certificat contindrà una extensió 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)
[...]
org.web3j
core
5.0.0
L’ordre carregarà la wallet a partir dels paràmetres.
Després d’uns instants la transacció serà incorporada a un bloc de la xarxa Ethereum de proves. Podem consultar l’estat de la transacció a etherscan:
https://goerli.etherscan.io/tx/…
Si tornem a consultar l’estat del certificat, obtindrem la marca de revocat
Las conclusions
La confiança és la clau. Per al sistema mostrat en aquest article confiem en la llista de certificats arrel que ve preconfigurada amb el navegador, als servidors DNS que tenim configurats per resoldre l’adreça IP d’un nom de domini. Així com els nodes inicials que ens permeten arrencar la xarxa d’Ethereum. En general, és millor evitar sistemes centralitzats que són més vulnerables que els seus equivalents descentralitzats. Les noves tecnologies descentralitzades reemplaçaran inevitablement a poc a poc les velles estructures. La redescentralització ha començat!
|