Study/study

AES ์•”ํ˜ธํ™” ๋ฐ์ดํ„ฐ ์ „์†ก ํ”„๋กœ๊ทธ๋žจ(C++) ๋ฆฌ๋ฒ„์‹ฑ

์œค์ •_ 2024. 11. 11. 17:16

๋ฐ์ดํ„ฐ๋ฅผ AES ์•”ํ˜ธํ™”ํ•˜์—ฌ ์†Œ์ผ“ ํ†ต์‹ ํ•˜๋Š” C++ ํ”„๋กœ๊ทธ๋žจ์„ ๋ฆฌ๋ฒ„์‹ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

OpenSSL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(v3.4.0)๋ฅผ ํ†ตํ•ด AES ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

#include <iostream>
#include <iomanip>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")

#define AES_KEY_SIZE 32  // AES-256
#define AES_BLOCK_SIZE 16

// AES ์•”ํ˜ธํ™” ํ•จ์ˆ˜ (EVP API ์‚ฌ์šฉ)
int aes_encrypt(const unsigned char* input, int input_len, unsigned char* output, const unsigned char* key, const unsigned char* iv) {
    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    if (!ctx) {
        std::cerr << "Error creating EVP context!" << std::endl;
        return -1;
    }

    int len;
    int ciphertext_len;

    if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
        std::cerr << "Error initializing encryption!" << std::endl;
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }

    if (1 != EVP_EncryptUpdate(ctx, output, &len, input, input_len)) {
        std::cerr << "Error during encryption!" << std::endl;
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }
    ciphertext_len = len;

    if (1 != EVP_EncryptFinal_ex(ctx, output + len, &len)) {
        std::cerr << "Error finalizing encryption!" << std::endl;
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }
    ciphertext_len += len;

    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

// ์†Œ์ผ“ ์ดˆ๊ธฐํ™” ๋ฐ ๋ฐ์ดํ„ฐ ์ „์†ก ํ•จ์ˆ˜
void send_encrypted_data(const char* host, int port, const unsigned char* encrypted_data, int data_len) {
    WSADATA wsaData;
    SOCKET sock;
    sockaddr_in server_addr;

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup failed" << std::endl;
        return;
    }

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {
        std::cerr << "Socket creation failed!" << std::endl;
        WSACleanup();
        return;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    inet_pton(AF_INET, host, &server_addr.sin_addr);

    if (connect(sock, (sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
        std::cerr << "Connection failed!" << std::endl;
        closesocket(sock);
        WSACleanup();
        return;
    }

    // ๋ฐ์ดํ„ฐ ์ „์†ก
    send(sock, (const char*)encrypted_data, data_len, 0);

    std::cout << "Encrypted data sent!" << std::endl;

    closesocket(sock);
    WSACleanup();
}

int main() {
    // AES ํ‚ค์™€ IV ์„ค์ •
    unsigned char key[AES_KEY_SIZE] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
    };  // 32 ๋ฐ”์ดํŠธ (AES-256)

    unsigned char iv[AES_BLOCK_SIZE] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
    }; // 16 ๋ฐ”์ดํŠธ (AES ๋ธ”๋ก ํฌ๊ธฐ)

    unsigned char input[] = "Hello, this is a test message for AES encryption!";
    unsigned char encrypted_data[1024];

    // ์•”ํ˜ธํ™”
    int encrypted_len = aes_encrypt(input, strlen((char*)input), encrypted_data, key, iv);

    if (encrypted_len < 0) {
        std::cerr << "Encryption failed!" << std::endl;
        return 1;
    }

    // ์†Œ์ผ“์„ ํ†ตํ•ด ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ ์ „์†ก
    send_encrypted_data("127.0.0.1", 8080, encrypted_data, encrypted_len);

    return 0;
}

 

 

 

์ˆ˜์ • ์ „ ์ฝ”๋“œ๋Š” key์™€ iv๋ฅผ ๋ฌธ์ž์—ด๋กœ ์ €์žฅํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

#define AES_KEY_SIZE 32
#define AES_BLOCK_SIZE 16
// ์ˆ˜์ • ์ „ key, iv
unsigned char key[AES_KEY_SIZE] = "0123456789abcdef0123456789abcdef";
unsigned char iv[AES_BLOCK_SIZE] = "0123456789abcdef";

 

 

๊ทธ๋Ÿฐ๋ฐ ํ•ด๋‹น ์†Œ์Šค์ฝ”๋“œ๋Š” ์˜ค๋ฒ„ํ”Œ๋กœ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด์œ ๋Š” key์™€ iv ๋ฐฐ์—ด ํฌ๊ธฐ์™€ ์ดˆ๊ธฐํ™” ๊ฐ’(๊ฐ 32, 16๋ฐ”์ดํŠธ)์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

C/C++ ๋ฌธ์ž์—ด ๋ฐ์ดํ„ฐ๋Š” ์ข…๋ฃŒ ๋ฌธ์ž(\0)๋ฅผ ํฌํ•จํ•˜๋ฏ€๋กœ
key์™€ iv์˜ ํฌ๊ธฐ๋Š” ์ข…๋ฃŒ ๋ฌธ์ž(\0) 1๋ฐ”์ดํŠธ๋ฅผ ํฌํ•จํ•œ ๊ฐ 33, 17๋ฐ”์ดํŠธ๊ฐ€ ๋˜์–ด ์˜ค๋ฒ„ํ”Œ๋กœ ์ด์Šˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿด ๋• ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฐ์—ด๋กœ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์ข…๋ฃŒ ๋ฌธ์ž๊ฐ€ ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ฐฐ์—ด์— ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

// ์ˆ˜์ • ํ›„ key, iv
unsigned char key[AES_KEY_SIZE] = {
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
};
unsigned char iv[AES_BLOCK_SIZE] = {
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
};

๋‚ด์šฉ๋„ ํ™• ๋ฐ”๋€Œ์—ˆ์ง€๋งŒ? ์•„๋ฌดํŠผ ์ˆ˜์ • ์™„๋ฃŒํ–ˆ์œผ๋‹ˆ ๋””์Šค์–ด์…ˆ๋ธ”์„ ์ง„ํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 


 

 

1. ๋ณ€์ˆ˜ ์ •์˜

 

 

  • xmmword
    128๋น„ํŠธ ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด
    xmm(128๋น„ํŠธ ํฌ๊ธฐ์˜ ๋ ˆ์ง€์Šคํ„ฐ) + word(๋ฐ์ดํ„ฐ)

 

IDA์— wmmword๊ฐ€ ์ˆซ์ž(hex)๋กœ ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณ€ํ™˜ ์ „

๋ณ€ํ™˜ํ•˜๋ฉด ๋ฐ˜๋Œ€๋กœ ๋’ค์ง‘ํžŒ ๋ฌธ์ž๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

๋ณ€ํ™˜ ํ›„

xmmword๋Š” 128๋น„ํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ ˆ์ง€์Šคํ„ฐ๋กœ 16๋ฐ”์ดํŠธ ๋ฌธ์ž์—ด์ด ํ•ด๋‹น ๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅ๋˜๋ฉด ๋ฌธ์ž์—ด์„ ์—ญ์ˆœ์œผ๋กœ ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๋ฐ”์ดํŠธ๋ฅผ ๋ฆฌํ‹€ ์—”๋””์–ธ ๋ฐฉ์‹์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋””๋ฒ„๊ฑฐ๋กœ ํ™•์ธํ•œ ์ „์ฒด ๋ฌธ์ž์—ด

 

  • ์—”๋””์–ธ(Endian)
    • ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์—ฌ๋Ÿฌ ๋ฐ”์ดํŠธ๋กœ ๊ตฌ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•  ๋•Œ ๊ทธ ์ˆœ์„œ(๋ฐ”์ดํŠธ ์ˆœ์„œ(byte order))๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฐœ๋…

 

  • ๋ฆฌํ‹€ ์—”๋””์–ธ(Little endian)
    • ์ž‘์€ ๋ฐ”์ดํŠธ๋ถ€ํ„ฐ ํฐ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹
      • ์ฒซ ๋ฒˆ์งธ ๋ฐ”์ดํŠธ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’!
    • ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฐ”์ดํŠธ(Most Significant Byte, MSB)๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ฐ€์žฅ ๋†’์€ ์ฃผ์†Œ์— ์ €์žฅ
    • x84, x64 ์‹œ์Šคํ…œ์„ ๋น„๋กฏํ•ด ๋Œ€๋ถ€๋ถ„์˜ ์•„ํ‚คํ…์ฒ˜๋Š” ๋ฆฌํ‹€ ์—”๋””์–ธ ๋ฐฉ์‹์„ ์‚ฌ์šฉ
    • ์˜ˆ์‹œ)
์ฃผ์†Œ 0x00 0x01 0x02 0x03
๊ฐ’ 0x78 0x56 0x34 0x12

 

  • ๋น… ์—”๋””์–ธ(Big endian)
    • ํฐ ๋ฐ”์ดํŠธ๋ถ€ํ„ฐ ์ž‘์€ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹
      • ์ฒซ ๋ฒˆ์งธ ๋ฐ”์ดํŠธ๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ฐ’!
    • ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฐ”์ดํŠธ(MSB)๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ฐ€์žฅ ๋‚ฎ์€ ์ฃผ์†Œ์— ์ €์žฅ
    • ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ(TCP/IP ๋“ฑ)์—์„œ ๋น… ์—”๋””์–ธ ๋ฐฉ์‹์„ ์‚ฌ์šฉ
    • ์˜ˆ์‹œ)
์ฃผ์†Œ 0x00 0x01 0x02 0x03
๊ฐ’ 0x12 0x34 0x56 0x78



 

2. ์•”๋ณตํ˜ธํ™”๋ฅผ ์œ„ํ•œ ์ค€๋น„

 

ํ•ด๋‹น ํ”„๋กœ๊ทธ๋žจ์€ ์•”๋ณตํ˜ธํ™” ์ž‘์—…์„ ์œ„ํ•ด EVP_CIPHER_CTX_new API๋ฅผ ํ˜ธ์ถœ

API ํ˜ธ์ถœ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€ ์ถœ๋ ฅ

 

  • EVP_CIPHER_CTX_new
    OpenSSL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋กœ ์•”ํ˜ธํ™” ๋ฐ ๋ณตํ˜ธํ™” ์ž‘์—…(์•”ํ˜ธํ™” API)์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”
    EVP_CIPHER_CTX ์ปจํ…์ŠคํŠธ ๊ตฌ์กฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๊ทธ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜

    • EVP_CIPHER_CTX
      OpenSSL์˜ ์•”/๋ณตํ˜ธํ™” ์ž‘์—…์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ƒํƒœ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ์ฒด
      ๋‹ค์–‘ํ•œ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์•”ํ˜ธํ™” ๋ฐ ๋ณตํ˜ธํ™”์˜ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ
      ํ‚ค, ์ดˆ๊ธฐ๋ฒกํ„ฐ(IV), ๊ธฐํƒ€ ํ•„์š”ํ•œ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ

 

 

 

3. AES-256 ์•”ํ˜ธํ™”

 

์†Œ์Šค์ฝ”๋“œ ํ๋ฆ„(IDA)

1) EVP_aes_256_cbc API ํ˜ธ์ถœ

2) EVP_EncryptInit_ex API ํ˜ธ์ถœ

  2-1) ์ˆ˜ํ–‰ ์ž‘์—… ์‹คํŒจ ์‹œ, ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€(Error initializing encryption!) ์ถœ๋ ฅ

3) EVP_EncryptUpdate API ํ˜ธ์ถœ

  3-1) ์ˆ˜ํ–‰ ์ž‘์—… ์‹คํŒจ ์‹œ, ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€(Error during encryption!)๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  LABEL_7๋กœ ์ด๋™

4) EVP_EncryptFinal_ex  API ํ˜ธ์ถœ

  4-1) ์ˆ˜ํ–‰ ์ž‘์—… ์‹คํŒจ ์‹œ, ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€(Error finalizing encryption!)๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  LABEL_7๋กœ ์ด๋™

5) EVP_CIPHER_CTX_free

6) ๋ณ€์ˆ˜ v7๊ฐ€ 0๋ณด๋‹ค ํฌ๋ฉด LABEL_13์œผ๋กœ ์ด๋™

 - v7์€ EVP_EncryptUpdate์—์„œ ๋ฐ˜ํ™˜๋œ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด(ํŒจ๋”ฉ์„ ํฌํ•จํ•œ ๋งˆ์ง€๋ง‰ ๋ธ”๋ก์˜ ๊ธธ์ด) v17๊ณผ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด v6๋ฅผ ๋”ํ•œ ๊ฐ’์œผ๋กœ, ์ตœ์ข…์ ์œผ๋กœ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ์ „์ฒด ๊ธธ์ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

* LABEL: ์–ด๋–ค ์กฐ๊ฑด๋ฌธ์ด๋‚˜ ๋ถ„๊ธฐ์— ์˜ํ•ด ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์ด ์ด๋™ํ•˜๋Š” ์ง€์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. if, goto, switch ๋˜๋Š” ํ•จ์ˆ˜ ๋ฐ˜ํ™˜ ๋“ฑ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ถ„๊ธฐ ๊ตฌ์กฐ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์†Œ์Šค์ฝ”๋“œ ํ๋ฆ„(C++)

C++ ์†Œ์Šค์ฝ”๋“œ

 

  • EVP_aes_256_cbc
    AES-256 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ CBC ๋ชจ๋“œ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜

  • EVP_EncryptInit_ex
    ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”(ex. AES, DES ๋“ฑ)์˜ ์ดˆ๊ธฐํ™”๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
    ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค์ •ํ•˜๊ณ  ๊ทธ์— ๋งž๋Š” ํ‚ค์™€ ์ดˆ๊ธฐ๋ฒกํ„ฐ(IV)๋ฅผ ์ง€์ •ํ•˜์—ฌ ์•”ํ˜ธํ™” ์ž‘์—…์„ ์ค€๋น„

  • EVP_EncryptUpdate
    ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”์—์„œ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋Š” ํ•จ์ˆ˜
    ์•”ํ˜ธํ™” ์ž‘์—…์€ ๋ฒ„ํผ ๋‹จ์œ„๋กœ ์ง„ํ–‰ํ•˜๊ณ  ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋Š” ์ถœ๋ ฅ ๋ฒ„ํผ์— ์ €์žฅํ•œ๋‹ค.

  • EVP_EncryptFinal_ex
    ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™” ์ž‘์—…์„ ๋งˆ๋ฌด๋ฆฌํ•  ๋•Œ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜
    ํ•„์š” ์‹œ ํŒจ๋”ฉ(padding)์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์™„์„ฑํ•œ๋‹ค.
     * ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™” ๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ธ”๋ก ๋‹จ์œ„๋กœ ์•”ํ˜ธํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์ง€๋ง‰ ๋ธ”๋ก์ด ๋ธ”๋ก ํฌ๊ธฐ์— ๋งž์ง€ ์•Š์œผ๋ฉด ํŒจ๋”ฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • EVP_CIPHER_CTX_free
    ์•”ํ˜ธํ™” ์ž‘์—…์„ ๋งˆ์นœ ํ›„ ์‚ฌ์šฉ๋œ ์•”ํ˜ธํ™” ์ปจํ…์ŠคํŠธ๋ฅผ ํ•ด์ œํ•˜๋Š” ํ•จ์ˆ˜
    ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์‚ฌ์šฉ์ด ๋๋‚œ ์•”ํ˜ธํ™” ๊ด€๋ จ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

 

 

4. ์†Œ์ผ“ ํ†ต์‹ 

4-1) socket ์ƒ์„ฑ

 

 

  • WSAStartup
    ์œˆ๋„์šฐ ์†Œ์ผ“ API(Winsock)๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ํ•จ์ˆ˜
    ๋„คํŠธ์›Œํฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ์†Œ์ผ“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”

  • socket
    ์†Œ์ผ“์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜

    • socket(2, 1, 6)
      - 2: AF_INET ⇒ IPv4
      - 1: SOCK_STREAM ⇒ TCP
      - 6: IPPROTO_TCP ⇒ TCP

 

 

์†Œ์ผ“(socket)

๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋˜๊ณ  ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค
IP ์ฃผ์†Œ ๋ฐ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ํ”„๋กœ๊ทธ๋žจ๊ณผ ํŠน์ • ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ์‹๋ณ„

 

์†Œ์ผ“ ๋‚ด๋ถ€ ๊ตฌ์กฐ

SOCKET WSAAPI socket(
  [in] int af,
  [in] int type,
  [in] int protocol
);
  • af
    ์ฃผ์†Œ ํŒจ๋ฐ€๋ฆฌ ์œ ํ˜•(์‚ฌ์–‘)
    ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ Winsock2.h ํ—ค๋”ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Œ
af AF_UNSPEC (0) AF_INET (2) AF_IPX (6) AF_APPLETALK (16) AF_NETBIOS (17) AF_INET6 (23) AF_IRDA
(26)
AF_BTH (32)
์˜๋ฏธ ์ง€์ • ์•ˆ ํ•จ IPv4 IPX/SPX AppleTalk NetBIOS IPv6 IrDA (์ ์™ธ์„  ๋ฐ์ดํ„ฐ ์—ฐ๊ฒฐ) Bluetooth

 

  • type
    ์†Œ์ผ“์˜ ํ˜•์‹
    ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ Winsock2.h ํ—ค๋”ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Œ
type  SOCK_STREAM (1) SOCK_DGRAM (2) SOCK_RAW
(3)
SOCK_RDM (4) SOCK_SEQPACKET
(5)
์˜๋ฏธ TCP UDP IPv4/IPv6 ํ—ค๋” ์˜ต์…˜ PGM ๋ฐ์ดํ„ฐ๊ทธ๋žจ ๊ธฐ๋ฐ˜ ๊ฐ€์ƒ ์ŠคํŠธ๋ฆผ(pseudo-stream) ํŒจํ‚ท

 

  • protocol
    ์‚ฌ์šฉํ•  ํ”„๋กœํ† ์ฝœ
    ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ Winsock2.h ๋ฐ Wsrm.h ํ—ค๋”ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Œ
protocol IPPROTO_ICMP
(1)
IPPROTO_IGMP
(2)
BTHPROTO_RFCOMM (3) IPPROTO_TCP
(6)
IPPROTO_UDP
(17)
IPPROTO_ICMPV6 (58) IPPROTO_RM
(113)
์˜๋ฏธ ICMP IGMP Bluetooth
RFCOMM
TCP UDP ICMPv6 PGM

 

 

 

4-2) IP ์ฃผ์†Œ ๋ฐ ํฌํŠธ ๋ฒˆํ˜ธ ์„ค์ •

 

 

  • name ⇒ sockaddr
    IPv4 ์ฃผ์†Œ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์กฐ์ฒด
    ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ๋•Œ ์‚ฌ์šฉ

 

sockaddr ๋ฐ sockaddr_in ๊ตฌ์กฐ์ฒด (IPv4)

struct sockaddr {
        ushort  sa_family;
        char    sa_data[14];
};

struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};

 

 

  • htons
    Host To Network Short
    ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
    ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ”์ดํŠธ ์ˆœ์„œ(์ฃผ๋กœ little endian)๋ฅผ ๋„คํŠธ์›Œํฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ”์ดํŠธ ์ˆœ์„œ(big endian)์œผ๋กœ ๋ณ€ํ™˜

    • htons(0x1F90u)
      0x1F90 = 8080
      ํฌํŠธ ๋ฒˆํ˜ธ: 8080

  • inet_pton
    IP ์ฃผ์†Œ ๋ฌธ์ž์—ด์„ ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
    IPv4 ๋˜๋Š” IPv6 ์ฃผ์†Œ๋ฅผ 32๋น„ํŠธ ๋˜๋Š” 128๋น„ํŠธ ์ด์ง„ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜

inet_pton ํ•จ์ˆ˜

 

 

inet_pton ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ

int inet_pton(int af, const char *src, void *dst);

 

  • af: ์ฃผ์†Œ ํŒจ๋ฐ€๋ฆฌ
    ⇒ RCX = 2
  • src: IP ์ฃผ์†Œ ๋ฌธ์ž์—ด
    ⇒ RDX = 127.0.0.1
  • dst: ๋ณ€ํ™˜๋œ ์ด์ง„ ํ˜•ํƒœ์˜ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•  ๋ฒ„ํผ
    ⇒ R8 = 000000078E1FF3EC

 

inet_pton ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด dst์— IP ์ฃผ์†Œ(src)๋ฅผ ์ด์ง„ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ €์žฅํ•˜๋Š”๋ฐ, ๋””๋ฒ„๊ฑฐ์—์„œ๋Š” ์ด๋ฅผ 16์ง„์ˆ˜๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ(์†Œ์ผ“) ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ IP ์ฃผ์†Œ๋ฅผ ์ด์ง„ ํ˜•์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋ฏ€๋กœ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณ€ํ™˜ ๊ณผ์ •์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค.

127.0.0.1 (DEC) = 01111111.00000000.00000000.00000001 (BIN) = 7F000001 (HEX)

๋ณ€ํ™˜๋˜์–ด ์ €์žฅ๋œ IP์ฃผ์†Œ

 

 

 

4-3) connect ๋ฐ send

 

connect ํ•จ์ˆ˜๋ฅผ ๋จผ์ € ํ˜ธ์ถœํ•˜์—ฌ ์—ฐ๊ฒฐ์— ์‹คํŒจํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€(Connection failed!)๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , ์„ฑ๊ณตํ•˜๋ฉด send ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก. ์ „์†ก์— ์‹คํŒจํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€(Encrypted data sent!)๋ฅผ ์ถœ๋ ฅ

 

  • connect
    ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜
    TCP ํ”„๋กœํ† ์ฝœ ์—ฐ๊ฒฐ์— ์‚ฌ์šฉ

  • send
    ๋ฐ์ดํ„ฐ๋ฅผ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ „์†กํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜
    TCP ํ”„๋กœํ† ์ฝœ ์†ก์ˆ˜์‹ ์— ์‚ฌ์šฉ

 

 

connect ํŒŒ๋ผ๋ฏธํ„ฐ 

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfdd
    ์—ฐ๊ฒฐํ•˜๋ ค๋Š” ์†Œ์ผ“์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋กœ socket ํ•จ์ˆ˜๋กœ ์ƒ์„ฑ๋œ ์†Œ์ผ“

  • addr
    ์„œ๋ฒ„์˜ ์ฃผ์†Œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” sockaddr(sockaddr _in) ๊ตฌ์กฐ์ฒด

  • addrlen
    addr(๊ตฌ์กฐ์ฒด)์˜ ํฌ๊ธฐ

 

addr(sockaddr_in) ๊ตฌ์กฐ์ฒด๋Š” ํŒจ๋ฐ€๋ฆฌ ์œ ํ˜•(2๋ฐ”์ดํŠธ) + ํฌํŠธ๋ฒˆํ˜ธ(2๋ฐ”์ดํŠธ) + IP์ฃผ์†Œ(4๋ฐ”์ดํŠธ) ์ด 8๋ฐ”์ดํŠธ์ง€๋งŒ, ์ตœ์ข…์ ์œผ๋กœ connect ํŒŒ๋ผ๋ฏธํ„ฐ์˜ 3๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ addrlen๋Š” 16(๋ฐ”์ดํŠธ)์ž…๋‹ˆ๋‹ค. ์ด๋Š” 8๋ฐ”์ดํŠธ์˜ ํŒจ๋”ฉ(padding) ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  • C/C++ ๊ตฌ์กฐ์ฒด์˜ ํŒจ๋”ฉ(padding)
    • ๋ฉ”๋ชจ๋ฆฌ ์ •๋ ฌ์„ ์œ„ํ•ด ์—ฌ๋ถ„์˜ ๋ฐ”์ดํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด์˜ ํ•„๋“œ๋“ค์„ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ ์ ˆํ•œ ๊ฒฝ๊ณ„์— ๋งž๊ฒŒ ๋ฐฐ์น˜ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.
    • ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜์—์„œ ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์„ ์œ„ํ•ด ์ •๋ ฌ(alignment)์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 4๋ฐ”์ดํŠธ ํฌ๊ธฐ์˜ ๋ฐ์ดํ„ฐ๋Š” 4๋ฐ”์ดํŠธ ๊ฒฝ๊ณ„์—์„œ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ์— ๋” ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. C/C++ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋Ÿฌํ•œ ์ •๋ ฌ์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ์ž๋™์œผ๋กœ ํŒจ๋”ฉ์„ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

4-4) socket ์ข…๋ฃŒ

 

 

  • closesocket
    ์†Œ์ผ“์„ ๋‹ซ๋Š” ํ•จ์ˆ˜
    ์†Œ์ผ“ ์‚ฌ์šฉ ํ›„ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•˜๊ณ  ์†Œ์ผ“์„ ๋‹ซ์„ ๋•Œ ์‚ฌ์šฉ

  • WSACleanup
    ์œˆ๋„์šฐ ์†Œ์ผ“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Winsock)๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ํ•จ์ˆ˜
    ์†Œ์ผ“ ๊ด€๋ จ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•˜๊ณ  Winsock ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ข…๋ฃŒ

  • 0i64
    64๋น„ํŠธ ์ •์ˆ˜ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    0: ์ˆซ์ž 0, i: signed, 64: 64๋น„ํŠธ
    ⇒ 64๋น„ํŠธ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜ํ˜• ๊ฐ’ 0์„ ์˜๋ฏธ

    • i64๋ฅผ ๋ถ™์ด๋Š” ์ด์œ ??
      0์„ ๊ทธ๋ƒฅ 0์ด๋ผ๊ณ  ์“ฐ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ 32๋น„ํŠธ ์ •์ˆ˜๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. 64๋น„ํŠธ ์ •์ˆ˜ ๊ฐ’์„ ๋ช…์‹œํ•˜๊ธฐ ์œ„ํ•ด i64๋ฅผ ๋ถ™์—ฌ ํƒ€์ž…์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต Rust ๊ฐ™์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ๋ณ€์ˆ˜ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. C++์˜ ํ‘œ์ค€ ๊ตฌ๋ฌธ์€ ์•„๋‹ˆ์ง€๋งŒ MSVC(Visual C++ ์ปดํŒŒ์ผ๋Ÿฌ)๋Š” i64 ๊ฐ™์€ ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์„ ๋ช…์‹œํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.