Frekuensi untuk Membangun Protokol Komunikasi yang Aman di C

Sebelum menyelam ke dalam implementasi, pastikan lingkungan pengembangan Anda termasuk sebuah kompiler C (GCC atau Clang), pengetahuan dasar pemrograman soket, dan pustaka OpenSSL terpasang. OpenSSL menyediakan implementasi yang kuat dari algoritme kriptografi, menjadikannya pilihan standar untuk komunikasi aman di C. Pada Linux, pasang OpenSSL melalui manajer paket Anda (mis., ). Pada Windows, gunakan binari atau build prakompilasi prakompilasi dari sumber. Familia dengan soket TCP/IP dan model klien-server juga diasumsikan.

Memahami Blok Bangunan Kriptografi

Protokol komunikasi yang aman didasarkan pada tiga pilar: kerahasiaan, integritas, dan otentikasi. Kepastian dicapai melalui enkripsi, memastikan bahwa hanya penerima yang dimaksudkan dapat membaca pesan. Integritas memastikan bahwa data belum diubah dalam transit. Otentikasi mengesahkan identitas pihak-pihak yang berkomunikasi. Dalam protokol gubahan, Anda biasanya menggabungkan enkripsi simetrik, hashing dengan kode otentikasi pesan (HMAC), dan mekanisme pertukaran kunci seperti Diffie ⁇ Hellman.

Simetri simetri simetris Penyulitan dengan AES

Keunggulan Kesulitan (AES) adalah cipher simetris yang paling banyak digunakan. Ia beroperasi pada blok 128-bit dan mendukung ukuran kunci 128, 192, atau 256 bit. Untuk komunikasi yang aman, lebih memilih AES dalam Galois/Counter Mode (GCM), yang menyediakan kerahasiaan maupun integritas dalam operasi tunggal. Antarmuka EVP OpenSSL membuatnya dengan mudah untuk mengenkripsi dan mendekripsi data dengan AES ⁇ GCM. Hindari mode yang lebih tua seperti ECB atau CBC kecuali jika dikombinasikan dengan pemadatan dan autentikasi.

Pertukaran Kunci Libur dengan Diffie ⁇ Hellman

Untuk secara aman setujui rahasia bersama melalui saluran yang tidak aman, gunakan pertukaran kunci Diffie ⁇ Hellman (DH) . Kedua pihak menghasilkan kunci pribadi dan pertukaran parameter publik, kemudian menghitung rahasia umum. Diffie ⁇ Hellman rentan terhadap manusia ⁇ dalam ⁇ serangan ⁇ middle jika tidak diotentikasi, sehingga Anda kemudian dapat memperpanjang ini dengan tanda digital atau kunci pra ⁇ dibagi. Untuk penggunaan produksi, pertimbangkan mempekerjakan ephealie ⁇ Hell (DHE) untuk memberikan kerahasiaan yang sempurna.

Integritas dan Pengesahan Pesan dengan HMAC

Untuk memverifikasi bahwa pesan belum dirusak, tambahkan Kode Otentikasi Pesan (HMAC) berbasis Hash (HMAC) ke setiap ciphertext yang terenkripsi. HMAC menggunakan kunci rahasia bersama dan fungsi hash kriptografi (misalnya, SHA ⁇ 25). Penerima mengkomput ulang HMAC pada data yang diterima dan membandingkannya dengan nilai yang ditransmisikan. Langkah ini mencegah replay dan serangan toran. Secara alternatif, AES ⁇ GCM termasuk tag autentikasi yang melayani tujuan yang sama, menyederhanakan protokol.

Pemanenan DVD dalam Projek C Anda

Ajang-Afolade OpenSSL memerlukan inisialisasi yang cermat. Sertakan header dan panggilan yang diperlukan dan pada awal program anda. Untuk penanganan kesalahan, gunakan dan . Ketika menghubungkan, tambahkan ke bendera kompiler anda. Sebuah setup minimal terlihat seperti ini:

#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();
}

¡Folder Gedung Lapisan Soket TCP

Pengangkutan yang mendasari untuk protokol Anda akan TCP, yang menyediakan pengiriman yang dapat diandalkan, diperintahkan. Membuat server yang mendengarkan koneksi masuk dan klien yang memulai jabat tangan. Gunakan soket POSIX standar dengan , , , , pada sisi server, dan , pada sisi klien. Ingat untuk menangani kesalahan secara anggun dan close berkas deskriptor setelah digunakan.

Sketsa Contoh Server sebol

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);

Skeleton Contoh Klien

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));

Mengimplementasi Pertukaran Kunci Diffie ⁇ Helleman

Setelah menetapkan koneksi TCP, klien dan server melakukan pertukaran kunci DH. Setiap pihak menghasilkan pasangan kunci DH menggunakan API OpenSSL. Kunci publik dikirim melalui soket, dan kedua belah pihak menghasilkan rahasia yang dibagikan menggunakan . Untuk kesederhanaan, gunakan grup prima tetap (contohnya, dengan parameter dari ). Dalam protokol nyata, Anda akan menegosiasikan kelompok atau menggunakan parameter pra-definisi.

// 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, &params);

// 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);

Pada akhir penerimaan, peer mengimpor kunci publik menggunakan dan kemudian memperoleh rahasia yang dibagikan. Rahasia turunan dapat di- hashed (contoh, dengan SHA ⁇ 56) untuk menghasilkan kunci seragam untuk AES dan HMAC.

Menghapuskan dan Menghapuskan Pesan dengan AES ⁇ GCM

AES ⁇ GCM adalah mode yang disukai karena menyediakan enkripsi maupun tag autentikasi dalam satu operasi. Gunakan dengan . Anda memerlukan nonce 12 ⁇ byte (IV) dan kunci 256 ⁇ bit yang berasal dari rahasia bersama DH. Ciphertext dihasilkan dalam potongan, dan setelah pembaruan akhir, Anda mengambil tag 16 ⁇ byte. Kirim nonce, ciphertext, dan tag bersama. Penerima melakukan , menetapkan tag, dan dekripsi. Jika tag verifikasi gagal, pesan ditolak.

// 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);

Menambah Integritas dengan HMAC (atau Tag GCM Pengalihan)

Jika anda tidak menggunakan AES ⁇ GCM, anda dapat mengenkripsi dengan AES ⁇ CBC dan kemudian menghitung sebuah HMAC melalui ciphertext. Gunakan dari OpenSSL dengan SHA ⁇ 256. Tambahkan HMAC setelah ciphertext. Penerima menghitung ulang dan membandingkan. Pendekatan ini memerlukan dua kunci: satu untuk enkripsi, satu untuk HMAC. Membiarkan keduanya dari rahasia bersama menggunakan fungsi derivasi kunci (KDF) seperti HCDF. Namun, AES ⁇ CMs menghilangkan HCMA yang terpisah, dan kemungkinan kesalahan.

Memutarnya Bersama: Aliran Kerja Lengkap

  1. Buatlah hubungan TCP antara klien dan server.
  2. Kedua belah pihak menghasilkan pasangan kunci ephemeral Diffie ⁇ Hellman.
  3. Bursa kunci publik dan menghitung rahasia bersama.
  4. Andaflive a 256 ⁇ bit kunci AES dan kunci HMAC 256 ⁇ bit (atau gunakan kunci yang sama untuk GCM).
  5. Klien NIS mengirimkan sebuah nonce (12 byte acak) dan kemudian pesan terenkripsi AES ⁇ GCM ditambah tag. Server menyahsulit dan mengverifikasi.
  6. Server afore mengirimkan tanggapan menggunakan nonce baru (tidak pernah menggunakan kembali nonce dengan kunci yang sama).
  7. Kedua belah pihak dapat terus bertukar pesan; untuk sesi panjang, kunci ulang secara berkala menggunakan jabat tangan DH yang sama atau mekanisme ratchet.

Praktek Terbaik Keamanan dan Kebidanan

  • toolhan Gunakan generator nomor acak kuat. Panggilan dari OpenSSL untuk menghasilkan kunci, nonces, dan kunci pribadi DH. Jangan pernah gunakan atau untuk tujuan kriptografi.
  • Parameter Validate semua data yang diterima. Periksa panjang, parameter kunci publik (mis., pastikan p adalah prima, g adalah generator), dan tag HMAC sebelum pemrosesan.
  • [[LOLT:0]]Avoid hardcoded keys atau defaults. Selalu runding kunci segar per sesi untuk memberikan kerahasiaan maju sempurna.
  • [EXALT:0]]Handle errors secara anggun. Jika dekripsi gagal atau verifikasi HMAC gagal, tutup sambungan dan log acara. Jangan ungkap mengapa kegagalan terjadi.
  • [[EFAILT:0]]Keep dependence updateed. Regularly update OpenSSL untuk patch kerentanan yang diketahui. OpenSSL dokumentasi menyediakan panduan pada deprekasi dan praktik terbaik.
  • [[ObleafFLT:0]]Pertimbangan penggunaan TLS daripada protokol gubahan. Untuk sistem produksi, bergantung pada protokol yang teruji dengan baik seperti TLS 1.3. Membangun protokol gubahan dari awal adalah kesalahan ⁇ prone dan tidak disarankan kecuali Anda memiliki keahlian kriptografi yang mendalam.

BARU Menguji Protokol

Uji implementasi Anda oleh menjalankan klien dan server pada mesin yang sama (localhost) dan verifikasi bahwa pesan didecrypt dengan benar. Perkenalkan kesalahan seperti ciphertext yang dirusak atau nonces yang tidak valid untuk memastikan bahwa protokol menolak mereka. Gunakan alat seperti Wireshark untuk memeriksa lalu lintas jaringan mentah dan konfirmasi bahwa teks biasa tidak terlihat. Untuk pengujian unit, mengejek lapisan soket dan uji kriptografi primitif secara terpisah.[ debuging OpenSSL dapat membantu verifikasi nilai intermediate yang diharapkan output.

Kekecualian Kesimpulan

Membina protokol komunikasi yang aman di C adalah latihan belajar yang sangat baik, tetapi membutuhkan perhatian teliti terhadap detail. Dengan mengtuaging OpenSSL yang terbukti implementasi Diffie ⁇ Hellman, AES ⁇ GCM, dan HMAC, Anda dapat membuat sistem yang menyediakan kerahasiaan, integritas, dan autentikasi. Selalu mengikuti praktik terbaik kriptografi: menggunakan kerawakan yang kuat, derive session key dengan KDF, tidak pernah menggunakan kembali nonces, dan validasi secara menyeluruh semua data. Untuk apa pun yang melampaui proyek pembelajaran, menganggap mengadopsi standar protokol seperti [[FLTL:0TL[TL], telah ditinjau secara rigorous dan ditinjau secara mendalam. Komunikasi yang aman adalah perbaikan yang berkelanjutan; muncul dari implementasi dan tetap dilakukan sesuai dengan ancaman.