Table of Contents
Edeltävät edellytykset turvallisen viestintäprotokollan rakentamiselle C:ssä
Ennen sukellusta toteutukseen, varmista kehitysympäristösi sisältää C-kääntäjän (GCC tai Clang), pistokeohjelmoinnin perustiedot ja OpenSSL-kirjaston asennettuna. OpenSSL tarjoaa vankat sovellukset salausalgoritmeista, joten se on vakiovalinta turvalliseen viestintään C. Linuxissa, asenna OpenSSL pakettihallintasi kautta (esim. ]). Windowsissa, käytä esipaketoituja binaareja tai rakenna lähde. Oletetaan myös, että TCP/IP-pistokkeilla ja asiakaspalvelinmallilla on oma tunnettuus.
Salaus- ja kryptografisten rakennuspalikoiden ymmärtäminen
Turvallinen viestintäprotokolla perustuu kolmeen pilariin: luottamuksellisuuteen, eheyteen ja todennukseen. Luottamuksellisuus saavutetaan salauksella, jolloin vain vastaanottaja voi lukea viestin. Tietosuoja varmistaa, ettei tietoja ole muutettu kauttakulussa. Todentaminen tarkastaa viestivien osapuolten henkilöllisyydet. Omassa protokollassa yhdistetään tyypillisesti symmetrinen salaus, häshing ja viestintunnistuskoodit (HMAC) sekä avainvaihtomekanismi kuten Diffie.
Symmetrinen salaus AES:n kanssa
Advanced Encryption Standard (AES) on yleisimmin käytetty symmetrinen salaus. Se toimii 128-bittisillä lohkoilla ja tukee avainkokoja 128, 192 tai 256 bittiä. Turvallisen viestinnän varmistamiseksi suosii AES Galois/Counter Mode (GCM), joka tarjoaa sekä luottamuksellisuutta ja eheyttä yhdessä toiminnossa. OpenSSL.SSL.S.VP-käyttöliittymä tekee yksinkertaiseksi salata ja purkaa tietoja AES-GCM:llä. Vältä vanhempia tiloja kuten EKP tai CBC, ellei siihen ole yhdistetty huolellista pehmustusta ja todentamista.
Avainvaihto Diffie...
Jotta voisimme turvallisesti sopia yhteisestä salaisuudesta vakuudettoman kanavan yli, käytä Diffie.Hellman (DH) -näppäinvaihtoa. Molemmat osapuolet luovat yksityisiä avaimia ja vaihtavat julkisia parametreja, sitten laskea yhteisen salaisuuden. [Diffie.Hellman[[] on altis ihmis-keskitason hyökkäyksille, jos niitä ei ole todennettu, joten voit myöhemmin laajentaa tätä digitaalisilla allekirjoituksilla tai ennalta jaetuilla avaimilla. Tuotannossa harkitsevat aikakausjulkaisujen käyttämistä, jotta he voisivat tarjota täydellisen salaisuuden eteenpäin.
Viestin luotettavuus ja todennus HMAC: lla
Varmistaaksesi, että viestiä ei ole peukaloitu, liitä Hash-pohjainen viestintunnistuskoodi (HMAC) jokaiseen salattuun salaustekstiin. HMAC käyttää jaettua salaista avainta ja salaushäshin toimintoa (esim. SHA-256). Vastaanotin palauttaa HMAC:n vastaanotetut tiedot ja vertaa sitä lähetettyyn arvoon. Tämä vaihe estää toiston ja peukaloinnin. Vaihtoehtoisesti AES-GCM sisältää tunnistautumistunnisteen, joka palvelee samaa tarkoitusta ja yksinkertaistaa protokollaa.
Avaa SSL C-projektissasi
OpenSSL vaatii huolellista alustamista. Sisällytä tarvittavat otsikot ja puhelu ja [ ohjelman alussa. Virheenkäsittelyä varten käytä ja . Kun liität, lisää [ kääntäjän liput.
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
// Initialize OpenSSL
void init_openssl() {
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
TCP Socket Layerin rakentaminen
Protokollan taustalla oleva kuljetus on TCP, joka tarjoaa luotettavan ja tilatun toimituksen. Luo palvelin, joka kuuntelee saapuvia yhteyksiä ja asiakas, joka käynnistää kädenpuristuksen. Käytä standardia POSIX-pistokkeita , , [], [[]] palvelimen puolella ja [], [[]] asiakkaan puolella. Muista käsitellä virheet hienosti ja sulje tiedostokuvaukset käytön jälkeen.
Palvelin Esimerkki Skeleton
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
bind(server_fd, (struct sockaddr*)&address, sizeof(address));
listen(server_fd, 3);
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
Asiakasesimerkki Skeleton
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
Diffie... Hellman Key Exchangen toteuttaminen
TCP-yhteyden perustamisen jälkeen asiakas ja palvelin tekevät DH-avaimenvaihdon. Jokainen puoli tuottaa DH-avaimenparin OpenSSL.s API:n avulla. Julkinen avain lähetetään pistorasian yli ja molemmat puolet johtavat yhteisen salaisuuden käyttäen [. Yksinkertaisuuden vuoksi käytä kiinteää prime-ryhmää (esim. ] ja []:n parametreja. Oikeassa protokollassa neuvottelisit ryhmästä tai käyttäisit ennalta määriteltyjä parametreja.
// Generate DH parameters
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
EVP_PKEY_paramgen_init(pctx);
EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, 2048);
EVP_PKEY *params = NULL;
EVP_PKEY_paramgen(pctx, ¶ms);
// Generate key pair
EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL);
EVP_PKEY_keygen_init(kctx);
EVP_PKEY *my_key = NULL;
EVP_PKEY_keygen(kctx, &my_key);
// Export public key to send
unsigned char *pub_key_der = NULL;
int pub_len = i2d_PUBKEY(my_key, &pub_key_der);
send(sock, pub_key_der, pub_len, 0);
Vastaanottavana osapuolena on julkinen avain ja sen jälkeen jaettu salaisuus. Johdettua salaisuutta voidaan hämmentää (esim. SHA-256) yhtenäisen avaimen tuottamiseksi AES:lle ja HMAC:lle.
Viestien salaaminen ja salauksen purkaminen AES-GCM:llä
AES-GCM on ensisijainen tila, koska se tarjoaa sekä salauksen että tunnistautumisen yhdessä toiminnossa. Käytä OpenSSL.s :a . Tarvitset 12-tavuisen nonce (IV):n ja 256-bittisen avaimen, joka on johdettu DH:n jaetusta salaisuudesta. Salaus on tuotettu paloina, ja lopullisen päivityksen jälkeen haet 16-tavuisen tagin. Lähetä ei-ce, salaus ja tag yhdessä. Vastaanotin suorittaa :n, asettaa tunnisteen ja purkaa salauksen. Jos tunnisteen todentaminen epäonnistuu, viesti hylätään.
// Encryption
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, nonce);
unsigned char ciphertext[1024];
int outlen;
EVP_EncryptUpdate(ctx, ciphertext, &outlen, plaintext, len);
int tmplen;
EVP_EncryptFinal_ex(ctx, ciphertext + outlen, &tmplen);
unsigned char tag[16];
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag);
Luotettavuuden lisääminen HMAC:n kanssa (tai GCM-tagi, jonka regenerointi on kesken)
Jos et käytä AES-GCM:ää, voit salata AES-CBC:llä ja laskea HMAC:n salauksen päälle. Käytä [ OpenSSL:stä SHA-2556:lla. Lisää HMAC:n salauksen jälkeen. Vastaanotin laskee ja vertaa. Tämä lähestymistapa vaatii kaksi avainta: yhden salauksen, yhden HMAC:lle. Aja sekä jaettua salaisuutta käyttäen avainta deduction-toiminnolla (KDF), kuten HKDF:llä. AES-GCM poistaa kuitenkin erillisen HMAC:n tarpeen, mikä vähentää monimutkaisuutta ja mahdollisia virheitä.
Pannaan se yhteen: Täydellinen työnkulku
- Luo TCP-yhteys asiakkaan ja palvelimen välille.
- Molemmat puolet tuottavat lyhytkestoisia Diffie-Hellman avainparia.
- Vaihda julkiset avaimet ja laske yhteinen salaisuus.
- AES-avain ja HMAC-avain 256-bittiselle näppäimelle (tai sama avain GCM:lle).
- Asiakas lähettää nonce (12 tavua satunnaista) ja sitten AES-GCM salattu viesti plus tag. Palvelin purkaa ja tarkastaa.
- Palvelin lähettää vastauksen käyttäen uutta nonce (koskaan uudelleenkäyttää nonces samassa avaimessa).
- Molemmat osapuolet voivat jatkaa viestien vaihtoa; pitkiä istuntoja varten uudelleenkäyttö säännöllisesti käyttäen samaa DH kädenpuristamista tai rattaiden mekanismia.
Turvallisuuden parhaat käytännöt
- Käytä vahvoja satunnaislukugeneraattoreita.[] Soita OpenSSL:stä luodaksesi avaimia, muita kuin näppäimiä ja DH yksityisiä avaimia. Älä koskaan käytä tai salaustarkoituksiin.
- Valitaan kaikki vastaanotetut tiedot.[[) Tarkista pituudet, julkiset avainparametrit (esim., varmista p on prime, g on generaattori), ja HMAC tagit ennen käsittelyä.
- Vältä kovakoodattuja avaimia tai oletusarvoja.[] Aina neuvotella avaimet tuoreina per istunto antaa täydellinen eteenpäin salaisuus.
- Käsivirheet hienovaraisesti.[ Jos salauksen purku epäonnistuu tai HMAC-tarkistus epäonnistuu, sulje yhteys ja kirjaa tapahtuma. Älä paljasta, miksi vika tapahtui.
- Pidä riippuvuussuhteet ajan tasalla.[ Päivitä OpenSSL säännöllisesti laastariin tunnettuja haavoittuvuuksia. [OpenSSL-dokumentaatio[ antaa ohjeita poistoista ja parhaista käytännöistä.
- Muokkaa TLS:n käyttöä mukautetun protokollan sijaan.[ Tuotantojärjestelmissä on hyvällä koetuksella testattuja protokollaa kuten TLS 1.3. Oman protokollan rakentaminen tyhjästä on virhealtista eikä sitä suositella, ellei sinulla ole syvää salausosaamista.
Pöytäkirjan testaus
Testaa toteutustasi ajamalla asiakasta ja palvelinta samalla koneella (localhost) ja tarkista, että viestit puretaan oikein. Ota käyttöön virheitä, kuten peukaloitu salausteksti tai virheellinen nonces, jotta protokolla ei läpäise niitä. Käytä työkaluja kuten Wiresharkia tarkastamaan raakaverkkoliikennettä ja varmista, että se ei ole näkyvissä. Unit testauksessa teetä pistokekerros ja testaa salaus primitiivisiä erikseen. OpenSSL. debugging voi auttaa todentamaan väliarvojen vastaa odotettuja lähtöjä.
Päätelmät
Luomalla turvallinen viestintäprotokolla C:hen on erinomainen oppimisharjoitus, mutta se vaatii huolellista huomiota yksityiskohtiin. OpenSSL. -ohjelmistojen avulla voidaan luoda järjestelmä, joka tarjoaa luottamuksellisuutta, eheyttä ja todennusta. Seuraa aina salausta parhaiden käytäntöjen avulla: käytä vahvaa satunnaisuutta, johdata istuntoavaimia KDF:llä, älä koskaan käytä uudelleen muita tietoja ja validoi kaikki tiedot. Jos jokin muu kuin oppimisprojekti, harkitse standardiprotokollan, kuten ]TLS 1.3[], jota on tarkasti tarkasteltu ja otettu käyttöön mittakaavassa. Turvallinen viestintä on jatkuva parannusprosessi; pysyttele ajan tasalla nousevista uhista ja päivitä toteutumisesi vastaavasti.