paint-brush
Xifratge: xifrats, resums, sal i IV: el que necessiteu saberper@gliimlang
Nova Història

Xifratge: xifrats, resums, sal i IV: el que necessiteu saber

per Gliimly14m2025/01/04
Read on Terminal Reader

Massa Llarg; Per llegir

El xifratge és un mètode per convertir les dades en una forma inutilitzable que només es pot fer útil mitjançant el desxifrat. Aquí, aprendràs a xifrar i desxifrar dades amb una contrasenya.
featured image - Xifratge: xifrats, resums, sal i IV: el que necessiteu saber
Gliimly HackerNoon profile picture

Què és el xifratge?

El xifratge és un mètode per convertir les dades en una forma inutilitzable que només es pot fer útil mitjançant el desxifrat. La finalitat és que les dades estiguin disponibles únicament per a aquells que les puguin desxifrar (és a dir, fer-les útils). Normalment, les dades s'han de xifrar per assegurar-se que no es poden obtenir en cas d'accés no autoritzat. És l'última línia de defensa després que un atacant hagi aconseguit trencar els sistemes d'autorització i control d'accés.

Això no vol dir que totes les dades s'hagin de xifrar, perquè sovint, els sistemes d'autorització i accés poden ser suficients i, a més, hi ha una penalització de rendiment per xifrar i desxifrar dades. Si i quan es xifren les dades és una qüestió de planificació de l'aplicació i avaluació de riscos i, de vegades, també és un requisit reglamentari, com ara HIPAA o GDPR.

Les dades es poden xifrar en repòs, com ara al disc, o en trànsit, com entre dues parts que es comuniquen per Internet.

Aquí, aprendràs a xifrar i desxifrar dades amb una contrasenya, també coneguda com a xifratge simètric. Aquesta contrasenya ha de ser coneguda per les dues parts que intercanvien informació.

Xifrat, Digest, Sal, Iteracions, IV

Per utilitzar correctament i de manera segura el xifratge, hi ha algunes nocions que cal explicar.


Un xifratge és l'algorisme utilitzat per a l'encriptació. Per exemple, AES256 és un xifrat. La idea d'un xifratge és el que la majoria de la gent pensarà quan es tracta de xifratge.


Un resum és bàsicament una funció hash que s'utilitza per codificar i allargar la contrasenya (és a dir, la clau de xifratge) abans que la utilitzi el xifratge. Per què es fa això? D'una banda, crea un hash ben aleatori i de longitud uniforme d'una clau que funciona millor per al xifratge. També és molt indicat per a la “saló”, que és el següent de què parlarem.


La "sal" és un mètode per derrotar les anomenades taules "arc de Sant Martí". Un atacant sap que dos valors hash seguiran semblant exactament iguals si ho fossin els originals. Tanmateix, si afegiu el valor de sal al hashing, no ho faran. Es diu "sal" perquè es barreja amb la clau per produir alguna cosa diferent.


Ara, una taula de l'arc de Sant Martí intentarà fer coincidir els valors hash coneguts amb dades precalculades per intentar endevinar una contrasenya.


Normalment, la sal es genera aleatòriament per a cada clau i s'emmagatzema amb ella. Per tal de fer coincidir els hash coneguts, l'atacant hauria de calcular prèviament les taules de l'arc de Sant Martí per a una gran quantitat de valors aleatoris, cosa que generalment no és factible.

Sovint sentireu parlar d'"iteracions" en el xifratge. Una iteració és un cicle únic en què una clau i una sal es barregen de manera que dificulta endevinar la clau. Això es fa moltes vegades per dificultar computacionalment que un atacant endevini la clau, per tant, "iteracions" (plural). Normalment, el nombre mínim d'iteracions requerit és de 1000, però pot ser diferent. Si comenceu amb una contrasenya molt segura, en general en necessiteu menys.

IV (o "Vector d'inicialització") és normalment un valor aleatori que s'utilitza per a l'encriptació de cada missatge. Ara, la sal s'utilitza per produir una clau basada en una contrasenya. I IV s'utilitza quan ja teniu una clau i ara esteu xifrant missatges. L'objectiu d'IV és fer que els mateixos missatges apareguin de manera diferent quan estan xifrats. De vegades, IV també té un component seqüencial, de manera que està format per una cadena aleatòria més una seqüència que augmenta constantment.


Això dificulta els atacs de "reproducció", que és on l'atacant no necessita desxifrar un missatge; més aviat, un missatge xifrat va ser "snifat" (és a dir, interceptat entre l'emissor i el receptor) i després es reproduïa, amb l'esperança de repetir l'acció ja realitzada. Tot i que, en realitat, la majoria de protocols d'alt nivell ja tenen una seqüència, on cada missatge té, com a part, un nombre de paquets creixent, de manera que en la majoria dels casos IV no ho necessita.

Requisits previs

Aquest exemple utilitza el marc Gliimly . Instal·leu- lo primer.

Exemple de xifratge

Per executar els exemples aquí, creeu una aplicació "enc" en un directori propi (vegeu mgrg per obtenir més informació sobre el gestor de programes de Gliimly):

 mkdir enc_example cd enc_example gg -k enc

Per xifrar dades, utilitzeu la declaració encrypt-data . La forma més senzilla és xifrar una cadena acabada en nul·la. Creeu un fitxer "encrypt.gliim" i copieu això:

 begin-handler /encrypt public set-string str = "This contains a secret code, which is Open Sesame!" // Encrypt encrypt-data str to enc_str password "my_password" p-out enc_str @ // Decrypt decrypt-data enc_str password "my_password" to dec_str p-out dec_str @ end-handler

Podeu veure l'ús bàsic d'encrypt-data i decrypt-data . Subministreu les dades (originals o encriptades) i la contrasenya, i endavant. Les dades es xifren i després es desxifren, donant lloc a l'original.

Al codi font, una variable de cadena "enc_str" (que es crea com a "char *") contindrà la versió xifrada de "Això conté un codi secret, que és Open Sesame!" i "dec_str" seran les dades desxifrades que han de ser exactament iguals.

Per executar aquest codi des de la línia d'ordres, feu primer l'aplicació:

 gg -q

A continuació, feu que Gliimly produeixi el codi bash per executar-lo: el camí de sol·licitud és "/encrypt", que, en el nostre cas, es gestiona per la funció "void encrypt()" definida al fitxer font "encrypt.gliim". A Gliimly, aquests noms sempre coincideixen, de manera que és fàcil escriure, llegir i executar codi. Utilitzeu l'opció "-r" a gg per especificar la ruta de sol·licitud i obtenir el codi que necessiteu per executar el programa:

 gg -r --req="/encrypt" --silent-header --exec


Obtindreu una resposta com aquesta:

 72ddd44c10e9693be6ac77caabc64e05f809290a109df7cfc57400948cb888cd23c7e98e15bcf21b25ab1337ddc6d02094232111aa20a2d548c08f230b6d56e9 This contains a secret code, which is Open Sesame!


El que teniu aquí són les dades xifrades, i després aquestes dades xifrades es desxifra amb la mateixa contrasenya. No és sorprenent que el resultat coincideixi amb la cadena que vau xifrar en primer lloc.

Tingueu en compte que, per defecte, encrypt-data produirà un valor xifrat en una forma hexadecimal llegible per humans, que vol dir que consta de caràcters hexadecimals "0" a "9" i "a" a "f". D'aquesta manera, podeu emmagatzemar les dades xifrades en una cadena normal. Per exemple, pot anar a un document JSON, a una columna VARCHAR d'una base de dades o pràcticament a qualsevol altre lloc. Tanmateix, també podeu produir dades xifrades binàries. Més sobre això en una mica.

Xifra les dades en un resultat binari

A l'exemple anterior, les dades xifrades resultants estan en forma hexadecimal llegible per humans. També podeu crear dades xifrades binàries, que no són una cadena llegible per l'home i també és més curta. Per fer-ho, utilitzeu la clàusula "binària". Substituïu el codi a "encrypt.gliim" per:

 begin-handler /encrypt public set-string str = "This contains a secret code, which is Open Sesame!" // Encrypt encrypt-data str to enc_str password "my_password" binary // Save the encrypted data to a file write-file "encrypted_data" from enc_str get-app directory to app_dir @Encrypted data written to file <<p-out app_dir>>/encrypted_data // Decrypt data decrypt-data enc_str password "my_password" binary to dec_str p-out dec_str @ end-handler

Quan vulgueu obtenir dades xifrades binàries, també hauríeu d'obtenir la seva longitud en bytes, o en cas contrari, no sabreu on acaba, ja que pot contenir bytes nuls. Utilitzeu la clàusula "longitud de sortida" per a aquest propòsit. En aquest codi, les dades xifrades de la variable "enc_str" s'escriuen al fitxer "encrypted_data" i la longitud escrita és "outlen" bytes.


Quan s'escriu un fitxer sense camí, sempre s'escriu al directori d'inici de l'aplicació (vegeu directoris ), de manera que haureu d'utilitzar get-app per obtenir aquest directori.

En desxifrar dades, observeu l'ús de la clàusula "longitud d'entrada". Diu quants bytes tenen les dades xifrades. Òbviament, podeu obtenir-ho de la variable "outlen", on encrypt-data emmagatzema la longitud de les dades xifrades. Quan el xifratge i el desxifrat estan desacoblats, és a dir, s'executen en programes separats, assegureu-vos que aquesta longitud estigui disponible.

Tingueu en compte també que quan les dades es xifren com a "binaris" (és a dir, produeixen una sortida binària), el desxifrat ha d'utilitzar el mateix.

Feu la sol·licitud:

 gg -q


Executeu-lo igual que abans:

 gg -r --req="/encrypt" --silent-header --exec


El resultat és:

 Encrypted data written to file /var/lib/gg/enc/app/encrypted_data This contains a secret code, which is Open Sesame!


Les dades desxifrades són exactament les mateixes que les originals.

Podeu veure les dades xifrades reals escrites al fitxer utilitzant la utilitat de Linux "octal dump" ("od"):

 od -c /var/lib/gg/enc/app/encrypted_data


amb el resultat com:

 $ od -c /var/lib/gg/enc/app/encrypted_data 0000000 r 335 324 L 020 351 i ; 346 254 w 312 253 306 N 005 0000020 370 \t ) \n 020 235 367 317 305 t \0 224 214 270 210 315 0000040 # 307 351 216 025 274 362 033 % 253 023 7 335 306 320 0000060 224 # ! 021 252 242 325 H 300 217 # \vm V 351 0000100

Aquí ho tens. Notareu que les dades són binàries i que en realitat conté els bytes nuls.

Xifrar dades binàries

Les dades a xifrar en aquests exemples són una cadena, és a dir, delimitades per nulls. Podeu xifrar les dades binàries amb la mateixa facilitat especificant-les senceres (ja que Gliimly fa un seguiment de quants bytes hi ha!) o especificant la seva longitud a la clàusula "longitud d'entrada", per exemple, copieu-ho a "encrypt.gliim":

 begin-handler /encrypt public set-string str = "This c\000ontains a secret code, which is Open Sesame!" // Encrypt encrypt-data str to enc_str password "my_password" input-length 12 p-out enc_str @ // Decrypt decrypt-data enc_str password "my_password" to dec_str // Output binary data; present null byte as octal \000 string-length dec_str to res_len start-loop repeat res_len use i start-with 0 if-true dec_str[i] equal 0 p-out "\\000" else-if pf-out "%c", dec_str[i] end-if end-loop @ end-handler

Això xifrarà 12 bytes a la ubicació de memòria "enc_str" independentment dels bytes nuls. En aquest cas, això és "Aquesta c" seguit d'un byte nul seguit d'una cadena "ontain", però pot ser qualsevol tipus de dades binàries, per exemple, el contingut d'un fitxer JPG.

Pel que fa al desxifrat, obtindreu el nombre de bytes desxifrats a la clàusula "longitud de sortida". Finalment, es mostra que les dades desxifrades són exactament l'original i el byte nul es presenta en una representació octal típica.

Feu la sol·licitud:

 gg -q


Executeu-lo igual que abans:

 gg -r --req="/encrypt" --silent-header --exec


El resultat és:

 6bea45c2f901c0913c87fccb9b347d0a This c\000ontai


El valor xifrat és més curt perquè les dades també són més curtes en aquest cas i el resultat coincideix exactament amb l'original.

Utilitzeu qualsevol xifrat o resum

El xifratge utilitzat per defecte és el hashing AES256 i SHA256 de la biblioteca estàndard d'OpenSSL , tots dos utilitzats àmpliament en criptografia. Tanmateix, podeu utilitzar qualsevol xifrat i resum disponible (és a dir, hash) que sigui compatible amb OpenSSL (fins i tot els personalitzats que proporcioneu).

Per veure quins algorismes estan disponibles, feu això a la línia d'ordres:

 #get list of cipher providers openssl list -cipher-algorithms #get list of digest providers openssl list -digest-algorithms


Aquests dos proporcionaran una llista d'algorismes de xifrat i digest (hash). Alguns d'ells poden ser més febles que els predeterminats escollits per Gliimly, i altres poden ser-hi només per compatibilitat amb sistemes antics. No obstant això, d'altres poden ser bastant nous i no han tingut prou temps per ser validats en la mesura que vulgueu que ho siguin.


Per tant, aneu amb compte a l'hora de triar aquests algorismes i assegureu-vos de saber per què esteu canviant els predeterminats. Dit això, aquí teniu un exemple d'ús de l'encriptació Camellia-256 (és a dir, "CAMELLIA-256-CFB1") amb el resum "SHA3-512". Substituïu el codi a "encrypt.gliim" per:

 begin-handler /encrypt public set-string str = "This contains a secret code, which is Open Sesame!" // Encrypt data encrypt-data str to enc_str password "my_password" \ cipher "CAMELLIA-256-CFB1" digest "SHA3-512" p-out enc_str @ // Decrypt data decrypt-data enc_str password "my_password" to dec_str \ cipher "CAMELLIA-256-CFB1" digest "SHA3-512" p-out dec_str @ end-handler


Feu la sol·licitud:

 gg -q


Executeu-ho:

 gg -r --req="/encrypt" --silent-header --exec


En aquest cas, el resultat és:

 f4d64d920756f7220516567727cef2c47443973de03449915d50a1d2e5e8558e7e06914532a0b0bf13842f67f0a268c98da6 This contains a secret code, which is Open Sesame!

De nou, obteniu les dades originals. Tingueu en compte que heu d'utilitzar el mateix xifrat i digerir tant en xifrar-dades com en desxifrar-dades!

Per descomptat, podeu produir el valor xifrat binari com abans utilitzant clàusules "binaris" i "longitud de sortida".

Si teniu sistemes externs que xifren dades i sabeu quin xifrat i quina digest utilitzen, podeu fer coincidir-los i fer que el vostre codi sigui interoperable. Gliimly utilitza la biblioteca estàndard d'OpenSSL, de manera que és probable que altres programaris també ho facin.

Ús de sal

Per afegir sal al xifratge, utilitzeu la clàusula "sal". Podeu generar sal aleatòria mitjançant la declaració de cadena aleatòria (o random-crypto si és necessari). Aquí teniu el codi de "encrypt.gliim":

 begin-handler /encrypt public set-string str = "This contains a secret code, which is Open Sesame!" // Get salt random-string to rs length 16 // Encrypt data encrypt-data str to enc_str password "my_password" salt rs @Salt used is <<p-out rs>>, and the encrypted string is <<p-out enc_str>> // Decrypt data decrypt-data enc_str password "my_password" salt rs to dec_str p-out dec_str @ end-handler


Feu la sol·licitud:

 gg -q


Executeu-lo unes quantes vegades:

 gg -r --req="/encrypt" --silent-header --exec gg -r --req="/encrypt" --silent-header --exec gg -r --req="/encrypt" --silent-header --exec


El resultat:

 Salt used is VA9agPKxL9hf3bMd, and the encrypted string is 3272aa49c9b10cb2edf5d8a5e23803a5aa153c1b124296d318e3b3ad22bc911d1c0889d195d800c2bd92153ef7688e8d1cd368dbca3c5250d456f05c81ce0fdd This contains a secret code, which is Open Sesame! Salt used is FeWcGkBO5hQ1uo1A, and the encrypted string is 48b97314c1bc88952c798dfde7a416180dda6b00361217ea25278791c43b34f9c2e31cab6d9f4f28eea59baa70aadb4e8f1ed0709db81dff19f24cb7677c7371 This contains a secret code, which is Open Sesame! Salt used is nCQClR0NMjdetTEf, and the encrypted string is f19cdd9c1ddec487157ac727b2c8d0cdeb728a4ecaf838ca8585e279447bcdce83f7f95fa53b054775be1bb2de3b95f2e66a8b26b216ea18aa8b47f3d177e917 This contains a secret code, which is Open Sesame!

Com podeu veure, es genera un valor de sal aleatori (16 bytes de llarg en aquest cas) per a cada xifratge, i el valor xifrat és diferent cada vegada, tot i que les dades que s'encripten eren les mateixes! Això fa que sigui difícil trencar el xifratge com aquest.

Per descomptat, per desxifrar, heu d'enregistrar la sal i utilitzar-la exactament com vau fer en xifrar. Al codi aquí, la variable "rs" conté la sal. Si emmagatzemeu els valors xifrats a la base de dades, probablement emmagatzemareu la sal just al costat.

Vector d'inicialització

A la pràctica, no utilitzaríeu un valor de sal diferent per a cada missatge. Cada vegada crea una clau nova i això pot reduir el rendiment. I realment no cal: l'ús de la sal és fer que cada clau (fins i tot les mateixes) sigui molt més difícil d'endevinar. Un cop ho hàgiu fet, potser no haureu de tornar a fer-ho, o sovint.

En comptes d'això, utilitzaríeu un IV (vector d'inicialització) per a cada missatge. Normalment és una cadena aleatòria que fa que els mateixos missatges semblin diferents i augmenta el cost computacional de trencar la contrasenya. Aquí teniu el codi nou per a "encrypt.gliim":

 begin-handler /encrypt public // Get salt random-string to rs length 16 // Encrypt data start-loop repeat 10 use i start-with 0 random-string to iv length 16 encrypt-data "The same message" to enc_str password "my_password" salt rs iterations 2000 init-vector iv cache @The encrypted string is <<p-out enc_str>> // Decrypt data decrypt-data enc_str password "my_password" salt rs iterations 2000 init-vector iv to dec_str cache p-out dec_str @ end-loop end-handler


Feu la sol·licitud:

 gg -q


Executeu-lo unes quantes vegades:

 gg -r --req="/encrypt" --silent-header --exec gg -r --req="/encrypt" --silent-header --exec gg -r --req="/encrypt" --silent-header --exec


El resultat pot ser:

 The encrypted string is 787909d332fd84ba939c594e24c421b00ba46d9c9a776c47d3d0a9ca6fccb1a2 The same message The encrypted string is 7fae887e3ae469b666cff79a68270ea3d11b771dc58a299971d5b49a1f7db1be The same message The encrypted string is 59f95c3e4457d89f611c4f8bd53dd5fa9f8c3bbe748ed7d5aeb939ad633199d7 The same message The encrypted string is 00f218d0bbe7b618a0c2970da0b09e043a47798004502b76bc4a3f6afc626056 The same message The encrypted string is 6819349496b9f573743f5ef65e27ac26f0d64574d39227cc4e85e517f108a5dd The same message The encrypted string is a2833338cf636602881377a024c974906caa16d1f7c47c78d9efdff128918d58 The same message The encrypted string is 04c914cd9338fcba9acb550a79188bebbbb134c34441dfd540473dd8a1e6be40 The same message The encrypted string is 05f0d51561d59edf05befd9fad243e0737e4a98af357a9764cba84bcc55cf4d5 The same message The encrypted string is ae594c4d6e72c05c186383e63c89d93880c8a8a085bf9367bdfd772e3c163458 The same message The encrypted string is 2b28cdf5a67a5a036139fd410112735aa96bc341a170dafb56818dc78efe2e00 The same message

Podeu veure que el mateix missatge sembla diferent quan es xifra, tot i que quan es desxifra, torna a ser el mateix. Per descomptat, la contrasenya, la sal, el nombre d'iteracions i el vector d'inici han de ser els mateixos tant per al xifratge com per al desxifrat.

Tingueu en compte l'ús de la clàusula "caché" a encrypt-data i decrypt-data. Emmagatzema de manera efectiva la clau calculada (contrasenya donada, sal, algorismes de xifrat/digest i el nombre d'iteracions), de manera que no es calcula cada vegada a través del bucle. Amb "cache", la clau es calcula una vegada, i després s'utilitza un IV diferent (a la clàusula "init-vector") per a cada missatge.

Si de tant en tant voleu reconstruir la clau, utilitzeu la clàusula "clear-cache", que proporciona un valor booleà. Si és cert, la clau es torna a calcular, en cas contrari, es deixa sola. Vegeu encrypt-data per obtenir més informació sobre això.

Conclusió

Heu après a xifrar i desxifrar dades mitjançant diferents xifratges, resums, sal i valors IV a Gliimly. També podeu crear un valor xifrat llegible pels humans i una sortida binària, així com xifrar tant cadenes com valors binaris (com els documents).