Criptografia
Introducció
Section titled “Introducció”La criptografia és un tema molt estens, però tens sort ja que només cal entendre algunes parts concretes de la criptografia per poder fer-la servir.
La criptografia en general té tres objectius:
- Integritat. Demostrar que el missatge no ha estat modificat, ni accidentalment ni deliberadament.
- Confidencialitat. Fer que el missatge sigui il·legible per a ningú, excepte el destinatari previst.
- No repudi. Poder demostrar que el missatge prové del remitent declarat.
Les diferents eines de criptografia admeten diferents aspectes d’aquests objectius.
Funcions hash
Section titled “Funcions hash”Una funció hash és com una caixa negra que pren una sola entrada i dóna una única sortida.
flowchart LR data["very long data"] hash["2d..e4"] data --> hash
Una funció hash pren una entrada de longitud arbitrària (un fitxer, un missatge, un vídeo, etc.) i produeix una sortida de longitud fixa (per exemple, 256 bits per a SHA-256).
Una funció hash pren com a entrada qualsevol seqüència de bytes que vulguis i produeix una seqüènica única de pocs bytes com a resultat.
Per exemple la funció SHA-256 sempre torna 32 bytes com a resultat, dona igual que la seqüència d’entrada sigui de 1000 bytes com de 2 Terabytes.
La seqüència de bytes por ser qualsevol cosa, un fitxer de video, audio, etc. perquè a la fi tots son bytes.
I el que és més important, donada la mateixa entrada, la funció hash sempre produeix la mateixa seqüència de bytes.
A un fitxer li pots canviar el nom, però sempre tindrà el mateix hash a no ser que el modifiquis.
Per això el hash pot identificar de manera unívoca un fitxer i el nom del fitxer no
Per qué serveix una funció hash?
Section titled “Per qué serveix una funció hash?”Ves a la pàgina web Ubuntu 22.04 LTS (Jammy Jellyfish) daily.
Desde la pàgina web em puc descarregar una ova, i com que és de la pàgina oficial d’Ubuntu puc suposar que no està manipulada.
$ wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.ova...[============================================================>] 601.11M 23.1MB/s in 30s2024-06-13 16:42:02 (19.7 MB/s) - ‘jammy-server-cloudimg-amd64.ova’ saved [630312960/630312960]
De totes maneres, i encara que gairebé ningú ho fa, en aquesta pàgina a més de baixar-te una ISO d’Ubuntu et pots baixar el hash de la ISO per confirmar que la còpia que et baixaràs d’un dels llocs de distribució d’Ubuntu no està manipulada:
{% image “ubuntu-ova-hash.png” %}
Si mires el contingut del fitxer SHA256SUMS
pots veure que té un hash de la iso.
$ wget -q https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS$ more SHA256SUMS | grep ova6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb69 *jammy-server-cloudimg-amd64.ova
El hash és de 32 bytes encara que l’ova sigui de 620MB!
openssl
és una aplicació que està instal.lada a tots els Linux, que entre altres coses em permet computar resums.
Per confirmar que tinc una còpia autèntica vaig a computar el hash de l’ova amb l’algorisme SHA-256:
$ openssl dgst -sha256 jammy-server-cloudimg-amd64.ovaSHA2-256(jammy-server-cloudimg-amd64.ova)= 6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb69$ more SHA256SUMS | grep ova6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb69 *jammy-server-cloudimg-amd64.ova
Els resums coincideixen!
Encara que canviï el nom del fitxer, el hash del fitxer continua sent el mateix:
$ mv jammy-server-cloudimg-amd64.ova ubuntu-jammy.ova$ openssl dgst -sha256 ubuntu-jammy.ovaSHA2-256(ubuntu-jammy.ova)= 6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb69$ cat SHA256SUMS | grep ova6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb69 *jammy-server-cloudimg-amd64.ova
De moment només farem servir -sha256 encara que hi ha altres funcions hash implementades:
$ openssl dgst -listSupported digests:-blake2b512 -blake2s256 -md4-md5 -md5-sha1 -ripemd-ripemd160 -rmd160 -sha1-sha224 -sha256 -sha3-224-sha3-256 -sha3-384 -sha3-512-sha384 -sha512 -sha512-224-sha512-256 -shake128 -shake256-sm3 -ssl3-md5 -ssl3-sha1
Propietats de la funció hash
Section titled “Propietats de la funció hash”Treballar amb ovas, isos, videos, audios, etc. està bé, excepte que són molt grans i requereixen bastant ample de banda.
Per aquest motiu baixarem el llibre Moby Dick; Or, The Whale i computar el hash del llibre:
$ wget -q https://www.gutenberg.org/cache/epub/2701/pg2701.txt -O moby-dick.txt$ ls -l moby-dick.txt-rw-r--r-- 1 david david 1276290 Jun 2 10:37 moby-dick.txt$ openssl dgst -sha256 moby-dick.txtSHA2-256(moby-dick.txt)= 15e0f2c564e3293775707c22d443c38d869caff7a9d2302293751c244712d81a
Per què serveix aquest hash que hem computat?
Ens proporciona integritat i autenticitat.
Si algú baixa la La Ilíada amb el nom de moby-dick.txt
, jo puc saber que han canviat el llibre sense necessitat d’obrir-lo si si quin és el hash de “Moby Dick”:
$ wget -q https://www.gutenberg.org/cache/epub/6130/pg6130.txt -O moby-dick.txt$ openssl dgst -sha256 moby-dick.txtSHA2-256(moby-dick.txt)= c333e6b96f5dad450a61007db0ec19836b5942f6a5a1efa7e1f3dd6804b19463
Pots veure que el hash c333..
no coincideix amb el hash 15e0..
de l’autèntic moby-dick.txt
.
Recupero el llibre original i problema soluctionat …
$ wget -q https://www.gutenberg.org/cache/epub/2701/pg2701.txt -O moby-dick.txt
a no ser que algú modifiqui la meva còpia sense que jo ho sapiga.
Si guardo el tamany del fitxer puc saber que ha estat manipulat si aquesta canvia …
$ ls -l moby-dick.txt-rw-r--r-- 1 david david 1161405 Jun 3 13:23 moby-dick.txt
Estás segur?
$ sed -i 's/Moby/Toby/g' moby-dick.txt$ ls -l moby-dick.txt-rw-r--r-- 1 david david 1161405 Jun 13 17:03 moby-dick.txt
El tamany del fitxer és el mateix, però ara on deia Moby diu Toby !
$ grep -o -i Moby moby-dick.txt | wc -l3$ grep -o -i Toby moby-dick.txt | wc -l86
Algún TOBY
s’ha escapat, en concret 3.
Queda clar que l’identificador del llibre ‘Moby Dick’ és 61d5ab6a3910fab66eabc9d2fc708b68b756199cb754fd5ff51751dbe5f766cd
.
Inclús en el Windows és el mateix:
> curl.exe -s https://www.gutenberg.org/cache/epub/2701/pg2701.txt -o moby-dick.txt> Get-FileHash .\moby-dick.txtAlgorithm Hash Path--------- ---- ----SHA256 15E0F2C564E3293775707C22D443C38D869CAFF7A9D2302293751C244712D81A C:\Users\david\moby-dick.txt
Hem utilitzat la funció hash SHA-256 per transformar l’entrada (el fitxer descarregat) en un identificador únic.
Resistència a la segona preimatge
Section titled “Resistència a la segona preimatge”Un hash pot garantir la integritat i l’autenticitat d’un fitxer si es gairebé imposible manipular un altre fitxer perquè computi el mateix hash, i així poder suplantar el fitxer original.
Les funcion hash segures tenen una propietat anomenada resistència a la segona preimatge.
Això vol dir que a partir del hash 362f76079b45e8d8b6c3380f0cec2dae4a12385bf06f200082b74f00fee2ed44
és gairebé impossible trobar o manipular un fitxer que computi el hash 362f76079b45e8d8b6c3380f0cec2dae4a12385bf06f200082b74f00fee2ed44
.
El hash sempre té la mateixa mida
Section titled “El hash sempre té la mateixa mida”Si apliquem la funció hash a la mateixa entrada sempre obtenim el mateix resum.
En el nostre exemple, SHA-256 sempre proporciona una sortida de 256 bits (32 bytes), que es codifiquen com 64 caràcters alfanumèrics en hexadecimal.
$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
Si vols ho podem provar 50 vegades si encara no estas convençut:
$ for i in {0..50}; do echo -c "Hello World!" | openssl dgst -sha256; doneSHA2-256(stdin)= 6e1f91f8c5fc22c805a65c1dc0969e02e02d55b9ede1ca28865f7d22425a9eafSHA2-256(stdin)= 6e1f91f8c5fc22c805a65c1dc0969e02e02d55b9ede1ca28865f7d22425a9eafSHA2-256(stdin)= 6e1f91f8c5fc22c805a65c1dc0969e02e02d55b9ede1ca28865f7d22425a9eaf...
{% panel “Notació hexadecimal” %}
Per representar el resum o hash, openssl fa servir notació hexadecimal.
Si contes la quantitat de caràcters que té la seqüència 362f76079b45e8d8b6c3380f0cec2dae4a12385bf06f200082b74f00fee2ed44
pots verificar que la longitut és de 64 caràcters.
Cada caràcter representa 4 bits, per tant la seqüencia és de (64 *4 ) = 256
bits (o 32
bytes). (256bits/8=32 bytes)
8 bits = 1 byte 🙄
Per aixó l’algoritme s’anomena SHA-256.
{% endpanel %}
Un petit canvi a l’entrada canvia completament la sortida:
$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "hello" | openssl dgst -sha256SHA2-256(stdin)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824$ echo -n "Hello!" | openssl dgst -sha256SHA2-256(stdin)= 334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7$ echo -n "Hllo" | openssl dgst -sha256SHA2-256(stdin)= 93c25d951f707030399c6a5573f9a4ed61529cb39ba5d4e7934ba6104811d358
La sortida de SHA-256 és sempre de la mateixa mida, independentment de la mida de l’entrada …
$ echo -n "" | openssl dgst -sha256SHA2-256(stdin)= e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "Hello World!" | openssl dgst -sha256SHA2-256(stdin)= 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069$ echo -n "Hola, Bonjour, こんにちは, 你好" | openssl dgst -sha256SHA2-256(stdin)= 4dfcaeacecfd67597e9e783e4da58d601745446a443ab7e8517d59695e2d81af
Funció unidireccional
Section titled “Funció unidireccional”Una de les propietats principals d’una funció hash és que no es pot revertir l’algorisme.
A partir d’un hash és impossible recuperar l’arxiu original.
Si esborres un video sense voler, però tens els seu hash f76f035ceef4e6f816ab4adf5f859a28f9fb248602af36aebf820661a172f3d0
, ¿creus que podries recuperar aquest video a partir d’aquests 32 bytes 🤔 ?
És impossible 😲!
Creus que podries escriure Don Quijote a partir d’aquesta frase:
“En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor.”
Funcions hash estandaritzades
Section titled “Funcions hash estandaritzades”Fins ara només hem utilitzat la funció SHA-256, que és una de les més utilitzades, però n’hi ha moltes altres.
Una funció hash dedica molt de temps a moure bits amunt i avall, barrejar-los, etc. tal com pots veure en aquest recurs web: https://sha256algorithm.com.
Precisament una de les característiques principals d’un bon algorisme hash és que sigui el més ràpid possible com veurem a continuació.
Funcions de detecció d’errors
Section titled “Funcions de detecció d’errors”No totes les funcions hash són criptogràfiques.
Per exemple, funcions com CRC32, són funcions de codi de detecció d’errors.
gzip
fa servir crc32
en els últims 8 bytes per detectar si hi ha hagut un error en la compressió:
$ echo -n "Hello" | gzip -1 -c | tail -c8 | hexdump -n4 -e '"%u\n"'4157704578
{% panel “How to calculate crc32 checksum from a string on linux bash” %}
gzip uses crc32 in the last 8 bytes and the -c option causes it to output to standard output and tail strips out the last 8 bytes. ( so we don’t waste time actually doing the compression).
hexdump
parse the gzip crc32 as a single 32-bit number:
-n4
takes only the relevant first 4 bytes of the gzip footer.'"%u"'
is your standard fprintf format string that formats the bytes as a single unsigned 32-bit integer. Notice that there are double quotes nested within single quotes here.
If you want a hexadecimal checksum you can change the format string to ’“%08x”’ (or ’“%08X”’ for upper case hex) which will format the checksum as 8 character (0 padded) hexadecimal.
{% endpanel %}
Aquestes funcions, tot i que detecten de manera útil alguns errors senzills, no proporcionen cap de les propietats de seguretat esmentades anteriorment i no s’han de confondre amb les funcions hash de les quals estem parlant (tot i que de vegades poden compartir el nom).
La seva sortida s’anomena normalment cheksum.
També pots instal.lar l’eina crc32
:
$ sudo apt install -y libarchive-zip-perl$ crc32 <(echo "Moby Dick")2096f510$ crc32 <(echo "Moby Dick")2096f510
Funcions hash criptogràfiques insegures
Section titled “Funcions hash criptogràfiques insegures”En la dècada de 1990 les funcions MD5
i SHA-1
eren les més utilitzades, però avui en dia es consideren que ja no són segures.
El 2004 es va demostrar que MD5
no era segur quan es van publicar col·lisions per diferents equips de recerca.
El 2016 va passar el mateix amb SHA1
.
Aquests atacs van tenir èxit en part a causa dels avenços en la informàtica, però sobretot perquè es van trobar defectes en la manera com es van dissenyar les funcions hash.
Una col.lisió es produeix quan dos fitxers diferents tenen el mateix hash, i normalment no passa de manera accidental.
Ves a https://gitlab.com/xtec/security/-/tree/main/crypto i observa com les imatges de allan.jpg
i james.jpg
són diferents.
Descarrega les imatges allan.jpg
i james.png
i verifica que tenen el mateix hash md5:
$ wget -q https://gitlab.com/xtec/smx-6/-/raw/main/crypto/allan.jpg$ openssl dgst -md5 allan.jpgMD5(allan.jpg)= e06723d4961a0a3f950e7786f3766338
$ wget -q https://gitlab.com/xtec/smx-6/-/raw/main/crypto/james.jpg$ openssl dgst -md5 james.jpgMD5(james.jpg)= e06723d4961a0a3f950e7786f3766338
En canvi amb sha-256
no hi ha col.lisió:
$ openssl dgst -sha256 allan.jpgSHA2-256(allan.jpg)= 1a072a5b8f988a4088a6ed42fac3011532a3d62fa85d0d0c76281a5a1fae2056$ openssl dgst -sha256 james.jpgSHA2-256(james.jpg)= 808e8a228d54cb6e43e9b22cf14d745db617622ec3d8e45fa8a1be68fbfe9ef4
Tenen el mateix hash perquè la imatge de James ha estat manipulada (s’han retocat alguns bits) perquè doni el mateix hash md5 que la imatge d’Allan.
Hi ha una col.lisió: el hash de md5
no identifica de manera unívoca una sól fitxer.
Recordes que el primer que hem fet en aquesta activitat era baixar una ova i verificar amb el hash que no havia estat manipulada?
Quan instal.les software amb apt
penses que no verifica de forma automàtica amb un hash el que està instal.lant?
I per quin motiu seguim parlant d’aquestes funcions 😒?
Entre altres motius perquè encara es fan servir i les pots trobar perquè són resistents a la preimatge (encara que no a la col.lisió).
És la funció hash més utilitzada i és la que hem estat fent servir fins ara.
Va ser desenvolupada per la NSA i estandarditzada pel NIST l’any 2001.
SHA-2
ofereix 4 versions diferents en funció del tamnay de la sortida: 224, 256, 384 o 512 bits.
El seus noms són: SHA-224
, SHA-256
, SHA-384
i SHA-512
.
Normalment es fa servir el SHA-256 que
proporciona els 128 bits de seguretat mínims necessaris avui en dia.
Encara que les aplicacions més paranoiaques fan servir SHA-512
.
Pots veure a continuació com per la mateixa entrada produeixen un hash de tamany diferent (el que li pertoca):
$ echo -n "Hello" | openssl dgst -sha224SHA2-224(stdin)= 4149da18aa8bfc2b1e382c6c26556d01a92c261b6436dad5e3be3fcc$ echo -n "Hello" | openssl dgst -sha256SHA2-256(stdin)= 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969$ echo -n "Hello" | openssl dgst -sha384SHA2-384(stdin)= 3519fe5ad2c596efe3e276a6f351b8fc0b03db861782490d45f7598ebd0ab5fd5520ed102f38c4a5ec834e98668035fc$ echo -n "Hello" | openssl dgst -sha512SHA2-512(stdin)= 3615f80c9d293ed7402687f94b22d58e529b8cc7916f8fac7fddf7fbd5af4cf777d3d795a7a00a16bf7e7f3fb9561ee9baae480da9fe7a18769e71886b03f315
Com hem explicat abans, una funció hash consumeix molt de temps.
La funció SHA-512
és més ràpida que la SHA-256
:
$ TIMEFORMAT=%R
$ time openssl dgst -sha256 ubuntu-jammy.ovaSHA2-256(ubuntu-jammy.ova)= 6b1a026eb2b881158abc8baf2d6f0a1f8e64656b740b7a133bbe42ed52f8cb691.809
$ time openssl dgst -sha512 ubuntu-jammy.ovaSHA2-512(ubuntu-jammy.ova)= 9ac849ff42d4b7a3a069650b858037fb0db70f576a06d22a59fea5a0bbd4df3dfc18e6a5956a8b0e6ebf05f73173e60e4afc9ed1bbb66ee07ae26f0efa78d89c1.378
Això passa perqè fem servir un processador de 64 bits.
Ara són molt habituals les CPUs de 64 bits, però a l’any 2001 la majoria de CPUs eren de 32 bits.
Un hash secret et permet fer un hash ràpidament d’un text sense exposar el text, el hash generat i l’algorisme utilitzat.
SHA-2 no es adequat per hash secrets degut a un problema de la construcció Merkle-Damgård, que fa que SHA-2 sigui vulnerable a un atac (anomenat atac d’extensió de longitud) si s’utilitza per hash secrets.
Aquí tens un video amb un exemple:
{% youtube “eNMpbJAjppc?si=6vGJhOdezgxcTrmU” %}
L’any 2007 el NIST va promoure un nou estàndard, i l’any 2015 l’algorisme SHA-3
es va estandarditzar a la Publicació FIPS 202.
SHA-3
és tant segur com SHA-2
i no és vulnerable als atacs d’extensió de longitud.
Per tant és pot utilitzar per hash secrets.
Ofereix les mateixes variants que SHA-2
, però hem d’indicar que es tracta de SHA-3
:
p$ echo -n "Hello" | openssl dgst -sha3-224SHA3-224(stdin)= 4cf679344af02c2b89e4a902f939f4608bcac0fbf81511da13d7d9b9$ echo -n "Hello" | openssl dgst -sha3-256SHA3-256(stdin)= 8ca66ee6b2fe4bb928a8e3cd2f508de4119c0895f22e011117e22cf9b13de7ef$ echo -n "Hello" | openssl dgst -sha3-384SHA3-384(stdin)= df7e26e3d067579481501057c43aea61035c8ffdf12d9ae427ef4038ad7c13266a11c0a3896adef37ad1bc85a2b5bdac$ echo -n "Hello" | openssl dgst -sha3-512SHA3-512(stdin)= 0b8a44ac991e2b263e8623cfbeefc1cffe8c1c0de57b3e2bf1673b4f35e660e89abd18afb7ac93cf215eba36dd1af67698d6c9ca3fdaaf734ffc4bd5a8e34627
Però només es fa servir en casos molts concrets perquè és molt més lent que SHA-2
:
$ time openssl dgst -sha512 ubuntu-jammy.ovaSHA2-512(ubuntu-jammy.ova)= 9ac849ff42d4b7a3a069650b858037fb0db70f576a06d22a59fea5a0bbd4df3dfc18e6a5956a8b0e6ebf05f73173e60e4afc9ed1bbb66ee07ae26f0efa78d89c1.280
$ time openssl dgst -sha3-512 ubuntu-jammy.ovaSHA3-512(ubuntu-jammy.ova)= 1930b1ef5144b333b88f4409626a4516691a6670d8e455f0cac7789ad5c8aff9eb0723ec455890d50f922ed8ff390ac9689714d056bdade0e31a6bf180cefb9b4.024
Funcions hash no estandaritzades
Section titled “Funcions hash no estandaritzades”El 2013, després de les revelacions d’Edward Snowden, es va descobrir que la NSA havia impulsat deliberadament i amb èxit la inclusió d’algoritmes de “backdoor” (porta del darrere) als estàndards (vegeu “Dual EC: A Standardized Back Door” de Bernstein et al.)
Aquests portes del darrere es poden considerar contrasenyes màgiques que permeten al govern (i només a ell, suposadament) subvertir el vostre xifratge.
Arran d’això, la comunitat criptogràfica va perdre molta confiança en els estàndards i els suggeriments procedents dels organismes governamentals.
Blake 2
Section titled “Blake 2”BLAKE2
és una funció hash criptogràfica més ràpida que MD5, SHA-1, SHA-2 i SHA-3, i almenys tan segura com SHA-3
.
BLAKE2
ha sigut adoptat per molts projectes per la seva alta velocitat, seguretat i senzillesa tal com pots veure en aquest enllaç: Blake2 - Users
Important! BLAKE2
es l’estandard de “facto”, però en àmbits públic com administracions públiques potser has de fer servir els estàndards oficials per obligació legal.
$ openssl dgst -blake2s256 ubuntu-jammy.ovaBLAKE2S-256(ubuntu-jammy.ova)= cbd6b7dd49001005fde431eb987aa0017050b05d851368091a6f111cbe3ade61$ openssl dgst -blake2b512 ubuntu-jammy.ovaBLAKE2B-512(ubuntu-jammy.ova)= b91cae689df79bb61f8449771b27d73e7d740e945d34d2fa87b39e38a18fbc6f723a3df06f9f4799dcacbc577a30fe964249ddd5fd6315715e49dfe98869a949
A continuació anem a verificar la velocitat de cada funcio hash:
$ time openssl dgst -md5 ubuntu-jammy.ovaMD5(ubuntu-jammy.ova)= a0914ee0cc3344277adf3027993fc0191.170$ time openssl dgst -sha1 ubuntu-jammy.ovaSHA1(ubuntu-jammy.ova)= fc09b6d6ce06ea0a92ab396c1814d47cd649b29e0.876$ time openssl dgst -sha-512 ubuntu-jammy.ovaSHA2-512(ubuntu-jammy.ova)= 9ac849ff42d4b7a3a069650b858037fb0db70f576a06d22a59fea5a0bbd4df3dfc18e6a5956a8b0e6ebf05f73173e60e4afc9ed1bbb66ee07ae26f0efa78d89c1.241$ time openssl dgst -sha3-512 ubuntu-jammy.ovaSHA3-512(ubuntu-jammy.ova)= 1930b1ef5144b333b88f4409626a4516691a6670d8e455f0cac7789ad5c8aff9eb0723ec455890d50f922ed8ff390ac9689714d056bdade0e31a6bf180cefb9b3.839$ time openssl dgst -blake2b-512 ubuntu-jammy.ovaBLAKE2B-512(ubuntu-jammy.ova)= b91cae689df79bb61f8449771b27d73e7d740e945d34d2fa87b39e38a18fbc6f723a3df06f9f4799dcacbc577a30fe964249ddd5fd6315715e49dfe98869a9491.039
SHA3-512
és la funció hash més lenta, i BLAKE2B-512
és la segona més ràpida i tan segura com SHA3-512
.
Ja pots intuïr perquè blake2 es la funció hash criptogràfica preferida si pots escollir.
Propietats d’una funció hash segura
Section titled “Propietats d’una funció hash segura”Aquestes són les propietats que ha de tenir una funció hash perquè sigui criptogràficament segura.
Farem servir aquest dades d’exemple:
$ echo -n "Hello World!" | openssl dgst -blake2b512BLAKE2B-512(stdin)= 54b113f499799d2f3c0711da174e3bc724737ad18f63feb286184f0597e1466436705d6c8e8c7d3d3b88f5a22e83496e0043c44a3c2b1700e0e02259f8ac468e
Recorda! És un exemple i el text d’entrada és molt petit.
Resistència prèvia a la imatge
Section titled “Resistència prèvia a la imatge”Per genera el digest
fem servir una funció hash aplicada a l’input
:
flowchart LR data["Hello Wordl!"] hash["54b113f..."] data -- Hash function--> hash
Però si només tens el digest
no pots reconstruir l’input
que es va fer servir per genera el digest
.
flowchart LR data["?"] hash["54b113f..."] hash -- Magic function--> data
Per exemple, encara que et mostri el hash tardarás uns quants dies en poder saber que estava escrit en el que havia on estan els ?
:
$ echo -n "????????????????????????????????????????????" | openssl dgst -blake2b512BLAKE2B-512(stdin)= 8b88ac87f7bda6f5e75e1ad15ca46b1749e048e3c9dd69f3afc55f797873ffe8cdd41c80d7eeed7b61bc7a52f56dcf3d24dc50a7d6a6fdaaf854d3ba975eb360
Resistència prèvia a la segona imatge
Section titled “Resistència prèvia a la segona imatge”Encara que tinguis linput
i el digest
:
flowchart LR data["Hello World!"] hash["54b113f..."] data -- Hash function--> hash
No podrás trobar un altre input
que generi el mateix digest
:
flowchart LR data["?"] hash[""54b113f...""] data -- Hash function--> hash
No et servei de res tenir la seqüènica original per produïr una altre seqüència que tingui el mateix hash:
$ echo -n "A cada ocellet li agrada el seu niuet" | openssl dgst -blake2b512BLAKE2B-512(stdin)= 76a432e02eadc7865a14385e617c4dbf884e6943edf1e8c629bcb6c680c401bfdfe20cb038aae35c701bbf903ea7e293fd661492850f33642346218f4476c9ea$ echo -n "A cada ocell li agrada el seu niuet" | openssl dgst -blake2b512BLAKE2B-512(stdin)= 9fc88211fc47b692dac2f26694463ac9ece42e1f9b205871ccd50d307316dbb259aaf6a4468d1ed7bacee497ba0a794b1c10d2c4d36dff8a066b9ed35c7a2eb8
Resistència a la col·lisió
Section titled “Resistència a la col·lisió”Ningú poc crear expressament una seqüència de bytes que produeixi el mateix hash que una altra seqüència de bytes.
Això no pot passar:
flowchart LR data1["Hello World!"] data2["Hello Barcelona!"] hash["54b113f..."] data1 -- Hash function--> hash data2 -- Hash function--> hash
Ja vam veure que això no és cert en MD5
, per això desde fa anys ja no és una fucnió hash segura.
Xifratge simètric
Section titled “Xifratge simètric”El xifratge “simètric” és el xifratge tradicional que existeix desde fa més de 4000 anys.
{% image “old-cipher.png” %}
Precisament, l’origen de la paraula criptografia el trobem en el grec antic: krypto, «ocult», i graphos, «escriure»; es a dir, escritura oculta.
Funcionament
Section titled “Funcionament”Un algorisme de xifratge (també anomenat xifrat) transforma una seqüència de bytes en quelcom que sembla aleatori.
L’algorisme de xifratge necessita:
- Una clau secreta (key) que es farà servir per xifrar el text
- Un text en clar (plaintext) que es que vos xifrar.
flowchart LR plaintext["plaintext 'Hello'"] key["key 0x8866..."] encrypt["Encrypt"] ciphertext["Ciphertext 0x6e0e..."] plaintext --> encrypt key --> encrypt encrypt --> ciphertext
Aquest procés de xifratge produeix text xifrat (chipertext)
El text xifrat sembla aleatori per a qualsevol persona que no coneix la clau secreta i no revela cap informació sobre el text original.
Pots utilitzar un algorisme de desxifrat per revertir el text xifrat al text pla original.
L’algorisme necessita:
- La mateixa clau secreta (key) que es va fer servir per crear el text xifrat.
- El text xifrat (chipertext) amb la clau secreta.
flowchart LR plaintext["plaintext 'Hello'"] key["key 0x8866..."] decrypt["Decrypt"] ciphertext["Ciphertext 0x6e0e..."] ciphertext --> decrypt key --> decrypt decrypt --> plaintext
El resultat és el text pla original (plaintext).
Un dels algorismes més utilitzats per xifrar és l’AES (estàndard de xifratge avançat).
Va ser publicat com estàndar pel NIST l’any 2001.
AES ofereix tres versions diferents:
- AES-128 pren una clau de 128 bits (16 bytes)
- AES-192 pren una clau de 192 bits (24 bytes)
- AES-256 pren una clau de 256 bits (32 bytes).
La longitud de la clau determina el nivell de seguretat: com més gran, més fort.
No obstant això, la majoria de les aplicacions fan servir AES-128
ja que proporciona prou seguretat (128 bits de seguretat).
Xifra el text
Section titled “Xifra el text”Podem xifrar un text amb openssl
tal com es mostra a continuació:
$ echo -n "Hello Wordl!" | openssl enc -e -base64 -aes-256-cbc -pbkdf2 -pass pass:very-secretU2FsdGVkX19oc9l8D8va99zJEsT5kQTUWK8UEhVdDak=
$ echo "U2FsdGVkX19oc9l8D8va99zJEsT5kQTUWK8UEhVdDak=" | openssl enc -d -base64 -aes-256-cbc -pbkdf2 -pass pass:very-secretHello Wordl!
L’opció -base64
indica a openssl que el resultat del xifratge es mostri en Base64.
D’aquesta manera tenim una seqüència de caràcters ASCII que es poden imprimir a la pantalla. Si no fem servir aquesta opció el resultat és una seqüència de bytes que no es poden mostrar per pantalla:
$ echo -n "Hello Wordl!" | openssl enc -e -aes-256-cbc -pbkdf2 -pass pass:very-secretSalted__j:�&�]���<��-�M��2��
L’opció -pbkdf2
es per utilitzar un mètode de derivació de clau concret.
Si no t’en recordes openssl
ja t’avisa!
`$ echo -n "Hello Wordl!" | openssl enc -e -base64 -aes-256-cbc -pbkdf2 -pass pass:very-secretU2FsdGVkX19IC6/ldMNq1yA3i5BUS96Y2FecqTfIxjk=$ echo -n "Hello Wordl!" | openssl enc -e -base64 -aes-256-cbc -pass pass:very-secret*** WARNING : deprecated key derivation used.Using -iter or -pbkdf2 would be better.U2FsdGVkX1/vdI65EMgqCGZVQcrSgzXFJt2sTIVdTBs=
A més de l’avís pots veure que el hash comença igual però acaba diferent.
Xifrar un fitxer
Section titled “Xifrar un fitxer”Normalment el que volem es xifrar un fitxer.
Crear un fitxer data.txt
i encripta el fitxer:
$ echo "Name: John Smith, Credit Card: 2332..33" > data.txt$ openssl enc -e -aes-256-cbc -pbkdf2 -pass pass:"very-secret" -in data.txt -out data.txt.enc$ cat data.txt.encSalted__sVA\[��I�F�rd'+�^3�O�k)/[d�@��,{���v"3�����]&�m
Per desencriptar el fitxer has de fer servir la mateixa clau:
$ rm data.txt$ openssl enc -d -aes-256-cbc -pbkdf2 -pass pass:"very-secret" -in data.txt.enc -out data.txt$ cat data.txtName: John Smith, Credit Card: 2332..33
Ús d’un fitxer de claus
Section titled “Ús d’un fitxer de claus”Les persones fem servir claus de xifratge curtes i fàcils de recordar.
Si volem xifrar una seqüència de bytes de manera segura és millor fer servir una bona clau de xifratge per si el “ciphertext” es interceptat d’alguna manera.
La forma de fer-ho és generar un fitxer que té la clau de xifratge i guardar aquest fitxer de manera segura.
$ openssl rand 256 > very-secret.key$ cat very-secret.key$���<��Z��a�fN$�VmX]����d�~�Tr���}�Cg�"V�#�+��0�+�����e��8��y�����R�� �J��F��}/iv�1'-=�-�"wi��<��sg��9-�: r�5�#d*ޒ4ˬ������;"F1�&�(�ǁRyįԟU����$�t�#��%փ��ˑMBWw�i�ĉ�~ӡp9���s�Q�.���t"��ݪ�~�AJ,�7���:���^�e4pU�$ openssl enc -e -aes-256-cbc -pbkdf2 -k very-secret.key -in data.txt -out data.txt.enc
Per desxifrar el text el procés és el mateix:
$ rm data.txt$ openssl enc -d -aes-256-cbc -pbkdf2 -k very-secret.key -in data.txt.enc -out data.txt$ cat data.txtName: John Smith, Credit Card: 2332..33
ChaCha20
Section titled “ChaCha20”AES és l’estàndard oficial, però ChaCha20 és més ràpid.
ChaCha és una família d’algorismes de xifrats creat per Daniel J. Bernstein per ser ràpid quan s’utilitza en programari, al contrari de l’AES, que és lent quan el suport de maquinari no està disponible.
Avui en dia, és àmpliament adoptat per protocols d’Internet com {% link “/network/tls/” %} i {% link “/network/wireguard/” %}.
L’únic que canvia a efecte pràctic es que enlloc de -aes-256-cbc
hem de posar -chacha20
:
$ openssl enc -e -chacha20 -pbkdf2 -k very-secret.key -in data.txt -out data.txt.enc$ rm data.txt$ openssl enc -d -chacha20 -pbkdf2 -k very-secret.key -in data.txt.enc -out data.txt$ cat data.txtName: John Smith, Credit Card: 2332..33
Velocitat
Section titled “Velocitat”Anem a veure quin dels dos és més ràpid!
$ TIMEFORMAT=%R$ time openssl enc -e -aes-256-cbc -pbkdf2 -k very-secret.key -in ubuntu-jammy.ova -out ubuntu-jammy.ova.enc2.370$ time openssl enc -e -chacha20 -pbkdf2 -k very-secret.key -in ubuntu-jammy.ova -out ubuntu-jammy.ova.enc1.521
Xifratge asimètric
Section titled “Xifratge asimètric”El xifratge asimètric es va inventar a finals de 1970 (RSA) i ha permés que les comunicacions per Internet siguin xifrades.
{% panel “Factorització d’enters 🐣 🐤 🐥 🦅” %}
-
El xifratge simètrica (la clàssica) utilitza una única clau per xifrar i desxifrar.
-
El xifratge asimètric:
-
Utilitza dues claus: una per xifrar i l’altre per desxifrar.
-
Una és pública (la puc compartir amb qui vulgui) i l’altre és privada (la guardo per mi).
-
I la pública és per xifrar o desxifrar 😐?
Per les dos coses 😳.
A la “Uni” és un rotllo matemàtic de bastantes hores de classe que es diu Factorització d’enters.
Per tant, presta un moment d’atenció!
{% endpanel %}
Primer haig de generar la clau privada:
$ openssl genpkey -algorithm RSA -out private.pem$ cat private.pem-----BEGIN PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmqAxS4TZkITcR...NqJthDb9w5BZAQbw0+DK+BQ=-----END PRIVATE KEY-----
Aquesta clau és la privada perquè ha de ser secreta, no la puc compartir.
Per quin motiu ha de ser secreta?
Perquè la segona clau, la “publica” la genero a partir d’aquesta clau!
$ openssl rsa -pubout -in private.pem -out public.pemwriting RSA key$ cat public.pem-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApqgMUuE2ZCE3EXBdpm1w...KQIDAQAB-----END PUBLIC KEY-----
Puc generar la clau privada a partir de la pública?
$ openssl rsa -pubout -in public.pem -out private.pemCould not read private key from public.pem4097EBB95A7F0000:error:1608010C:STORE routines:ossl_store_handle_load_result:unsupported:../crypto/store/store_result.c:151:4097EBB95A7F0000:error:1608010C:STORE routines:ossl_store_handle_load_result:unsupported:../crypto/store/store_result.c:151:
La clau privada genera la clau pública, però la clau pública no pot generar la privada.
{% emoji ”🌈” %}
Xifrar dades
Section titled “Xifrar dades”Si la Laura em vol enviar un missatge secret pot utilitzar la meva clau pública que tinc accessible a tothom.
$ echo "Quedem dimarts a les 12 al Zurich de Plaça Catalunya" > message.txt$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in message.txt -out message.txt.enc$ rm message.txt$ cat message.txt.enc
Important! Recorda de borrar el fitxer message.txt.enc
si existeix perquè openssl
per precaució no sobreesciurà el fitxer.
Només qui té la clau privada, se suposa que només jo 🙄, pot desencriptar aquest missatge:
$ openssl pkeyutl -decrypt -inkey private.pem -in message.txt.enc -out message.txt$ cat message.txtQuedem dimarts a les 12 al Zurich de Plaça Catalunya
Una de les coses sorprenents del xifratge asimètric és que cada cop que xifro el mateix missatge el missatge xifrat és diferent:
$ rm message.txt.enc$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in message.txt -out message.txt.enc$ openssl dgst -blake2s256 message.txt.encBLAKE2S-256(message.txt.enc)= 8a837220d83c323768be0e7fc7174845663a82acfdaab5cc3984608287d89e23$ openssl pkeyutl -decrypt -inkey private.pem -in message.txt.encQuedem dimarts a les 12 al Zurich de Plaça Catalunya
$ rm message.txt.enc$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in message.txt -out message.txt.enc$ openssl dgst -blake2s256 message.txt.encBLAKE2S-256(message.txt.enc)= 44f3b9559fae4ee970dac8f19deea99eeb06a8a9139c72fe81f16da7cdd9abb5$ openssl pkeyutl -decrypt -inkey private.pem -in message.txt.encQuedem dimarts a les 12 al Zurich de Plaça Catalunya
$ rm message.txt.enc$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in message.txt -out message.txt.enc$ openssl dgst -blake2s256 message.txt.encBLAKE2S-256(message.txt.enc)= e8e334a3e466f057768500411cf022da36c45975f746a7ef957b92b1b8ef663f$ openssl pkeyutl -decrypt -inkey private.pem -in message.txt.encQuedem dimarts a les 12 al Zurich de Plaça Catalunya
Això és molt important perquè puc escriure el mateix missatge encriptat tantes vegades com vulgui i ningú pot saber que és el mateix missatge.
Missatges petits
Section titled “Missatges petits”La criptografía asimètrica (o de clau pública) és molt poc eficient en temps de computació.
Necessita milers de vegades més potència de càlcul per xifrar, desxifrar i validar que els algorismes simètrics.
I openssl
es nega a fer-ho si l’arxiu és una mica gran:
$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in moby-dick.txt -out moby-dick.txt.encPublic Key operation error40376248027F0000:error:0200006E:rsa routines:ossl_rsa_padding_add_PKCS1_type_2_ex:data too large for key size:../crypto/rsa/rsa_pk1.c:133:
openssl
diu que no! Motiu: data too large for key size
.
El problema és que una clau RSA pot ser de de 1024, 2048 o 4096 bits (per defecte és de 2048 bits).
I té uns limits molt petits respecte el tamany del missatge que pot encriptar: (TODO simplificar)
-
Una clau RSA de 1024-bit fent servir padding OAEP pot encriptar com a màxim (1024/8) – 42 = 128 – 42 = 86 bytes.
-
Una clau RSA de 2048-bit pot encriptar com a màxim (2048/8) – 42 = 256 – 42 = 214 bytes.
Per això la criptografia pública només es pot fer servir per encriptar:
- Hash
- Claus simètriques
- Missatges molt curts
Compartir una clau secreta
Section titled “Compartir una clau secreta”Si per exemple la Laura em vol enviar “Moby Dick” encriptat el que ha de fer és:
- Crear una clau simètrica temporal (AES o ChaCha20)
- Encriptar ‘Moby Dick’ amb la clau simètrica temporal
- Publicar ‘Moby Dick’ encriptat.
$ openssl rand 128 > moby.key$ openssl enc -e -chacha20 -pbkdf2 -k moby.key -in moby-dick.txt -out moby-dick.txt.enc$ curl -T moby-dick.txt.enc https://oshi.at
https://oshi.at/a/3f4760c1873e254c4b5ab8786781cd4b60b06ba0 [Admin]https://oshi.at/ibYw [Download]http://5ety7tpkim5me6eszuwcje7bmy25pbtrjtue7zkqqgziljwqy3rrikqd.onion/ibYw [Tor download]
Pots veure que tothom que tingui l’enllaç pot tenir el fitxer encriptat, però no pots saber que hi ha en aquest fitxer.
{% image “oshi-at.png” %}
El problema es que per desencriptar necessito la clau moby.key
😆!
Ara el problema és com la Laura em pot enviar la clau moby.key
de manera segura.
Com que la clau és petita la Laura pot utilitzar la criptografia asimètrica:
- Encripta
moby.key
amb la meva clau pública - Publica la clau simètrica encriptada
$ openssl pkeyutl -encrypt -inkey public.pem -pubin -in moby.key -out moby.key.enc$ curl -T moby.key.enc https://oshi.at
https://oshi.at/a/85fd211456f9cb44a0c2e84094cc0499547a7cfe [Admin]https://oshi.at/RhAC [Download]http://5ety7tpkim5me6eszuwcje7bmy25pbtrjtue7zkqqgziljwqy3rrikqd.onion/RhAC [Tor download]
Borra tots els fitxers “moby”:
$ rm moby*
⊞ Windows
Obre una sessió de Powershell en un Windos o inicia sessió en una altre màquina (per exemple, a Isard).
El que haig de fer a continuació per recuperar “Moby Dick” és:
- Baixar els dos fitxers
- Desencriptar
moby.key.enc
amb la clau privadaprivate.pem
que has creat - Desencriptar el fitxer
moby-dick.text.enc
amb la clau simètricamoby.key
.
# (1) Baixo els dos fitxers$ curl -s https://oshi.at/ibYw -o moby-dick.txt.enc$ curl -s https://oshi.at/RhAC -o moby.key.enc
# (2) Desencripto la clau simètrica (AES)$ openssl pkeyutl -decrypt -inkey private.pem -in moby.key.enc -out moby.key
# (3) Desencripto el llibre amb la clau simètrica (AES)$ openssl enc -d -chacha20 -pbkdf2 -k moby.key -in moby-dick.txt.enc -out moby-dick.txt
# (4) Ja tinc accés al llibre$ cat moby-dick.txt | head -2The Project Gutenberg eBook of Moby Dick; Or, The Whale
{% panel “Resum” %}
{% emoji ”🦄” %}
Pots veure que per enviar qualsevol fitxer encriptat a alguna persona només necessito que ell em doni una clau pública RSA.
Puc enviar el que vulgui a aquella persona que només ell podrà desencriptar el fitxer encara que tothom pugui tenir una còpia del fitxer encriptat.
A l’activitat {% link “/security/gpg/” %} veurem com l’eina gpg
ens permete fer tot això i molt més de manera molt senzilla (si saps el que estas fent, per això fem aquesta activitat).
{% endpanel %}
Signatura
Section titled “Signatura”En l’activitat anterior la Laura m’ha enviat un missatge i un llibre.
Però com puc estar segur que me l’ha enviat la Laura?
La criptografia asimètrica de clau pública també s’ocupa de solucionar el problema de l’autenticitat.
Primer fem que la Laura generi les seves claus:
$ openssl genpkey -quiet -algorithm RSA -out laura_private.pem$ openssl rsa -pubout -in laura_private.pem -out laura_public.pemwriting RSA key
Si la laura em vol enviar un missatge que només jo pugui llegir i que jo pugui confirmar que l’ha escrit la Laura:
-
La Laura ha de generar un hash del missatge i encriptar el hash del missatge amb la seva clau privada (això es coneix com firmar un missatge).
-
Ha de tonar a encriptar el missatge amb la meva clau pública.
El primer que ha de fer és firmar el missatge:
$ echo "Quedem dilluns a les 10 a la cafeteria de l'Institut" > message.txt$ openssl dgst -sha256 -sign laura_private.pem -out message.txt.signed message.txt
$ openssl base64 -in message.txt.signedrurwwPWSFiEebwlEwMXldyP6DfCcBg/pePyqBsofLPpclo785jmJkTW1Zo8Ki76C73e36KRR0OW18OSCqLA4ol2iA+Nh38q1o97YZIwQ9B3CYBkxNqZxY/ccMga9pvxp30y/Cyf+NkP+cXFqdiR9IG+RZKtTsO3Rc+FlKLap1bTV/xtjnrG1q+fCFUnKJLJ51ihQJQPd1EdzVdS7IAlydlZgEik8xDUtuT+EDozPI9fKBdotwIldWOzqZDJEjkaTea6/UbgtAtEvxJowcrEMbiXzS3WBOVxzZZKyZKNG2p3n5B1qAtifT/O9E6kQfRCk8+rkAO477QT/OHh4YnX4bg==
El contingut del missatge és el hash SHA256
del fitxer message.txt
codificat amb la clau privada laura_private.pem
:
$ openssl dgst -sha256 message.txtSHA2-256(message.txt)= b455f09698edff582b4102065734dc87326d59949c6ebabe6ac6abbeb704cf92
Puc verificar que la Laura ha firmat el missatge perquè la clau pública de la Laura, i només la Laura, pot decodificar el contingut del fitxer message.txt.signed
i que el resultat sigui el hash de message.txt
:
$ openssl dgst -verify laura_public.pem -signature message.txt.signed message.txtVerified OK
Si per exemple provo amb la meva clau pública dona error:
$ openssl dgst -verify public.pem -signature message.txt.signed message.txtVerification failure40E7936B1F7F0000:error:02000084:rsa routines:rsa_ossl_public_decrypt:data too large for modulus:../crypto/rsa/rsa_ossl.c:661:40E7936B1F7F0000:error:1C880004:Provider routines:rsa_verify:RSA lib:../providers/implementations/signature/rsa_sig.c:774:
{% panel “Que és una signatura?” %} {% emoji ”🦄” %}
{% emoji "" %} És un hash d’un fitxer encriptat amb la clau privada d’alguna persona.
Com que només la clau publica d’aquesta persona pot “desencriptar” el hash, sabem que aquella signatura pertany a aquella persona.
Altre cosa és qui té accés a aquella clau privada … no està ben guardada, la tenim vàries persones, etc.
Però això ja no són coses d’informàtica.
{% emoji ”🙄” %} {% endpanel %}
Windows
Section titled “Windows”Fes el mateix amb el Windows.
Consulta tot el que vulguis a Internet, excepte les solucions que tens en aquest document.
Baixa els dos fitxers:
{% sol %}
> curl.exe -s https://oshi.at/ibYw -o moby-dick.txt.enc> curl.exe -s https://oshi.at/RhAC -o moby.key.enc> Get-ChildItem -Filter moby*
Directory: C:\Users\david\tmp
Mode LastWriteTime Length Name---- ------------- ------ -----a---- 15/06/2024 10:20 1161421 moby-dick.txt.enc-a---- 15/06/2024 10:20 256 moby.key.enc
{% endsol %}
Si intento obrir el fitxer moby-dick.txt.enc
…
{% image “notepad-enc.png” %}
Necessito la clau simètrica per desencriptar el fitxer.
Però el fitxer moby.key.enc
també està encriptat.
Necessito la clau privada que ha encriptat moby.key.enc
i només qui tingui aquesta clau podrà accedir.
Doncs ja pots passar la clau private.pem
del Linux al Windows, i no preguntis al professor com fer-ho que ja t’has de poder espabilar per tu mateix.
{% sol %}
> $rsa = New-Object -TypeName System.Security.Cryptography.RSACryptoServiceProvider
(todo)
> [byte[]]$str = Get-Content "moby.key.enc" -Encoding Byte> $DecryptedStr = $rsa.Decrypt($str, $false);> Write-Host "File content : " $DecryptedStr
{% endsol %}
TODO RSA Encrypt Text In PowerShell
Python
Section titled “Python”Per treballar amb Python farem servir la llibreia pycryptdome.
Instal.la la llibreria amb pip
:
$ pip install pycryptodome
Primer generem les claus RSA (1024 bits) i les imprimim a la consola (com a números hexadecimals i en el format PKCS#8 PEM ASN.1
).
Crea un nou fitxer crypto.py
:
from Crypto.PublicKey import RSA
keyPair = RSA.generate(1024)
pubKey = keyPair.publickey()print(f"Public key: (n={hex(pubKey.n)}, e={hex(pubKey.e)})", end="\n\n")pubKeyPEM = pubKey.exportKey()print(pubKeyPEM.decode("ascii"), end="\n\n")
print(f"Private key: (n={hex(pubKey.n)}, d={hex(keyPair.d)})", end="\n\n")privKeyPEM = keyPair.exportKey()print(privKeyPEM.decode("ascii"))
Executa el codi:
$ python3 crypto.pyPublic key: (n=0x9846e53267677f0d6e913c6ea274fd6ea5394a800ce688548e95295517b2298341081bb9badaf9bc778dc2b8f503cb444db1c7bd8a675c02947bf69872ed80e8f50961f27737012ea231fecafdeb4bec826258e71ce2f24a3bbe9e8b0df5bf13e2ce41428dfc2eab329b3aced399432d907702defd3ed15189a25aa7c71dcaeb, e=0x10001)
-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYRuUyZ2d/DW6RPG6idP1upTlKgAzmiFSOlSlVF7Ipg0EIG7m62vm8d43CuPUDy0RNsce9imdcApR79phy7YDo9Qlh8nc3AS6iMf7K/etL7IJiWOcc4vJKO76eiw31vxPizkFCjfwuqzKbOs7TmUMtkHcC3v0+0VGJolqnxx3K6wIDAQAB-----END PUBLIC KEY-----
Private key: (n=0x9846e53267677f0d6e913c6ea274fd6ea5394a800ce688548e95295517b2298341081bb9badaf9bc778dc2b8f503cb444db1c7bd8a675c02947bf69872ed80e8f50961f27737012ea231fecafdeb4bec826258e71ce2f24a3bbe9e8b0df5bf13e2ce41428dfc2eab329b3aced399432d907702defd3ed15189a25aa7c71dcaeb, d=0x803f0a68c38da158bea0b2df651302735d28e85afa826d44499120ee4eb6a31fad20170efa6a7c49adfbf0ddb4a72d59fe7feba8f0c226a0f04ce15ccdee18d22229229e29aa36ae95db74431c5cf4827d4556bf341958643a6c4e7d0242e8b1abdd3b8c71d0782ede1a2ecd0b0698776b50ee3357e01a3ebd9455c9a599319)
-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQCYRuUyZ2d/DW6RPG6idP1upTlKgAzmiFSOlSlVF7Ipg0EIG7m62vm8d43CuPUDy0RNsce9imdcApR79phy7YDo9Qlh8nc3AS6iMf7K/etL7IJiWOcc4vJKO76eiw31vxPizkFCjfwuqzKbOs7TmUMtkHcC3v0+0VGJolqnxx3K6wIDAQABAoGACAPwpow42hWL6gst9lEwJzXSjoWvqCbURJkSDuTrajH60gFw76anxJrfvw3bSnLVn+f+uo8MImoPBM4VzN7hjSIikinimqNq6V23RDHFz0gn1FVr80GVhkOmxOfQJC6LGr3TuMcdB4Lt4aLs0LBph3a1DuM1fgGj69lFXJpZkxkCQQC8/QFtogF6ZXaA4Z78CL0irPTnussJK1SJbmevaT4LXU6cuVx+p1+1qqApalAlYhd0OAkAgo+IBiAsROFh1hDHAkEAzkV/Ij/ot6yXUvf5ff0Yn7Log2IMB2IYQ++NK6nDpgM3fEaGMVV0ZrJ2DGMVKNyE8BoMrIH3T0lF5n9o9jlYvQJBAIpVW41HL3PK/wH5pGjxcJgIJ7/TT7jneZqbMNQJ4ftpkhhP6e9fTkRon5GRGxcyBN7yAUzZRHyZl0UwKhV2HpMCQQCwHPAOOwikAcz1vtkas8SZXXRd8JGaoCtdnaMnm3t7O5XdGo2qg26t3EMkEljXmWg7Y9JcW17fKA1xXmksiQv1AkB+EcEGK4TcD/6jIc/8wV3CdlBprWwsIXDAvQO8QsU9Pcf/JLN72xtbk8PeWwy759OOFdCVrJ/DYPcX5Toe43KM-----END RSA PRIVATE KEY-----
Pots veure que el tamany de la clau és bastant llarg encara que sigui de 1024 bits.
Peró en un ús real tindries que utilitzar una clau RSA de 3072 o 4096 bits.
{% panel “Factorització d’enters” %}
Però el més important és que pots veure el contingut real de les claus:
- La clau pública es composa de 2 números:
n
ie
. - La clau privada es composa de 2 números:
n
id
.
Quan fem les activitats de {% link “/network/ssh/” %}, {% link “/network/tls/” %}, etc. veurás molts cops les claus en format ASCII.
Però ara pots veure que es tracta de números, no de lletres, i que la criptografia asimètrica es basa en fer servir números molts grans que són especials per fer uns càlculs senzills mijantçant Factorització d’enters.
Per conduïr un cotxe no cal ser un enginyer, només tenir uns conceptes bàsics de com funciona un cotxe.
Per cert, el número que s’ha de mantenir secret és el d
🤐.
{% endpanel %}
A continuació, xifra el missatge mitjançant l’esquema de xifratge RSA-OAEP (RSA amb padding PKCS#1 OAEP) amb la clau pública RSA:
from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEPimport binascii
keyPair = RSA.generate(1024)pubKey = keyPair.publickey()
msg = b'A message for encryption'encryptor = PKCS1_OAEP.new(pubKey)encrypted = encryptor.encrypt(msg)print("Encrypted:", binascii.hexlify(encrypted))
Executa l’script crypto.py
:
$ python3 crypto.pyEncrypted: b'93440b3838d91e1f7d3980d2dd2c14b17f4e8c322dab1ed325cb83f49b10866ddaac7d35de1788a5232cfd0cb25d8cf8f2b4221bf3ba3554bc37269fd7dcc1aca356ddea35a1e0afe0b9b1b764b74ae3d37ac68b37399480caacb0d0ffca46444380abc2de3e73ccd3b671dc3c0e6f4bbcb3fadecc1754fcd34063fa30a65b0b'
A continuació desxifra el missatge fent servir RSA-OAEP amb la clau privada RSA:
from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEPimport binascii
keyPair = RSA.generate(1024)pubKey = keyPair.publickey()
msg = b'A message for encryption'encryptor = PKCS1_OAEP.new(pubKey)encrypted = encryptor.encrypt(msg)print("Encrypted:", binascii.hexlify(encrypted))
decryptor = PKCS1_OAEP.new(keyPair)decrypted = decryptor.decrypt(encrypted)print('Decrypted:', decrypted)
Pots veure que el missatge es desxifra sense problemes:
$ python3 crypto.pyEncrypted: b'320626aa408f39908e7734f5dfc5ae515ca1b2a149d01c02eca2f74c8a2011e2c9a59fe60cbbbd4be9af0122340092bdce348b0ca9835a1346365877f937b4a142c1e0640295964522c5e52f448f7cc99c5e31877b96485c11e631da8eb0cf164b8e5b2ed097b6f24d389f9eb0cbf46822cc41036b2d852d1b163c8a86441c52'Decrypted: b'A message for encryption'
Per saber més
Section titled “Per saber més”[TODO] Article s’ha d’adaptar (versió 0.03 pycoin problema import) https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-examples
Activitats
Section titled “Activitats”1.- Has aconseguit obtenir una clau que et permet desxifrar un missatge molt secret que utilitza ChaCha20, però et falta l’últim digit: very-secret-
El missatge és U2FsdGVkX1+c11lZXqn7akxqW+3Z8RjqGvGF16/RSeReLnDC
Quin és el contingut del missatge?
{% sol %}
$ echo "U2FsdGVkX1+c11lZXqn7akxqW+3Z8RjqGvGF16/RSeReLnDC" | openssl enc -d -base64 -chacha20 -pbkdf2 -pass pass:very-secret-8Missatge molt secret
{% endsol %}
2.- Descarrega el llibre A Tail of Two Cities en format text UTF-8 i computa el hash blake2b512
.
{% sol %}
$ wget -q https://www.gutenberg.org/files/98/98-0.txt -O book.txt$ wc -l book.txt16285 book.txt$ openssl dgst -blake2b512 book.txt > book.txt.hash$ cat book.txt.hashBLAKE2B-512(book.txt)= 1a8ac18fde710ecc452770fcd52a2c4945d40c71467b2cd4c64a7b5308261078201cefdb6ddc682a67511aa60992324c5ff87e29192adfd8f113a1e6030b0459
{% endsol %}
Encripta el llibre amb AES i ChaCha
{% sol %}
$ openssl enc -e -aes-256-cbc -pbkdf2 -pass pass:very-secret -in book.txt -out book.txt.enc_aes$ openssl enc -e -chacha20 -pbkdf2 -pass pass:very-secret -in book.txt -out book.txt.enc_chacha$ ls -l book.txt*-rw-r--r-- 1 david david 807231 Mar 27 2021 book.txt-rw-r--r-- 1 david david 807248 Jun 14 18:58 book.txt.enc_aes-rw-r--r-- 1 david david 807247 Jun 14 18:58 book.txt.enc_chacha-rw-r--r-- 1 david david 152 Jun 14 18:54 book.txt.hash
Pots veure que el fitxer encriptat i els encriptats tenen gairebé el mateix tamany! {% endsol %}
Elimina el llibre original, recupera els llibres encriptats i verifica que les còpies desencriptades són el mateix que l’original.
{% sol %}
$ cat book.txt.hashBLAKE2B-512(book.txt)= 1a8ac18fde710ecc452770fcd52a2c4945d40c71467b2cd4c64a7b5308261078201cefdb6ddc682a67511aa60992324c5ff87e29192adfd8f113a1e6030b0459
$ rm book.txt$ openssl enc -d -aes-256-cbc -pbkdf2 -pass pass:very-secret -in book.txt.enc_aes -out book.txt$ openssl dgst -blake2b512 book.txtBLAKE2B-512(book.txt)= 1a8ac18fde710ecc452770fcd52a2c4945d40c71467b2cd4c64a7b5308261078201cefdb6ddc682a67511aa60992324c5ff87e29192adfd8f113a1e6030b0459
$ rm book.txt$ openssl enc -d -chacha20 -pbkdf2 -pass pass:very-secret -in book.txt.enc_chacha -out book.txt$ openssl dgst -blake2b512 book.txtBLAKE2B-512(book.txt)= 1a8ac18fde710ecc452770fcd52a2c4945d40c71467b2cd4c64a7b5308261078201cefdb6ddc682a67511aa60992324c5ff87e29192adfd8f113a1e6030b0459
{% endsol %}
El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.
©2022-2025 xtec.dev