[C++] OpenSSL을 이용한 간단한 echo 프로그래밍
우선 구현하기에 앞서 SSL 통신에 필요한 certificate를 하나 생성하자
위의 명령어를 입력하면 "mycert.pem" 이라는 Certificate File 이 하나 만들어진다
Client 부분 먼저 코딩을 해 보았다
1.소켓 생성하고 서버에게 연결요청하기
socket() 함수를 이용하여 소켓을 생성한다 → sockaddr_in 함수를 이용하여 서버의 IP주소와 PORT를 지정한다 → connect() 함수를 이용하여 서버로 연결을 요청한다.
헤더 | #include <sys/socket.h> #include <arpa/inet.h> |
코드 | int connectServer(const char *hostname, int port) sd = socket(PF_INET, SOCK_STREAM, 0); if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) |
- int socket(int protocolFamily, int type, int protocol)
인자1 ) protocolFamaily : 프로토콜 체계를 말한다 PF_INET 은 인터넷 프로토콜을 의미한다.
인자2 ) type : 서비스 타입으로 프로토콜마다 3가지 방식(STREAM, DGRAM, RAW)이있다. SOCK_STREAM 은 tcp 방식을 의미한다.
인자3 ) protocol : 소켓에서 사용할 프로토콜이다 type에서 미리 정해진 경우 인자로 0을 넣는다.
반환값 : 소켓생성 실패 -1, 성공 fd>0
- int connect ( int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
인자1) sockfd : 소켓 스크립터
인자2) serv_addr : 서버 주소 정보 구조체를 가르키는 포인터
인자3) addrlen : 서버 주소 정보 구조체의 크기
반환값 : 연결 성공 0 , 연결 실패 -1
- 주소구조체 sockaddr_in , sockaddr
sockaddr_in | sockaddr |
short sin_family | u_short safamily |
u_short sin_port | char sa_data[14] |
struct in_addr sin_addr | |
char sin_zero[8] |
2. 암호화 통신을 위한 초기화 작업을 한다 → SSL_CTX_new 함수를 이용하여 ssl_ctx 를 생성한다.
헤더 | #include <openssl/ssl.h> #include <openssl/err.h> |
코드 | SSL_CTX* InitCTX(void) |
* 초기화에 있어 반드시 필요한 함수는 아래와 같다.
(1) void SSL_load_error_strings(void); - 에러메시지 문자열들을 로드한다.
(2) void SSL_library_init(); - OpenSSL에서 사용될 알고리즘들을 초기화한다.
(3) TLSv1_2_client_method(void); -메소드함수를 이용해 클라이언트의 통신 방식을 tls1.2 프로토콜로 지정한다.
(SSL_METHOD : SSL 버전을 나타낸다. 각버전에 따라 지원되는 알고리즘이나 프로토콜 형식은 다르다)
3. SSL_new 함수를 이용하여 SSL(구조체)을 생성한다 → SSL_set_fd 함수를 이용하여 현재 소켓과 ssl 연결
SSL *ssl; ssl = SSL_new(ctx); SSL_set_fd(ssl, server); |
* SSL : SSL_CTX를 이용하여 생성된다. SSL 구조체는 ssl 통신을 하는 상대서버와 관련된 구조체로 상대방과 연결하고 초기 협상과정을 진행하며 데이터를 주고받는 일을 한다.
4. SSL_connect 함수를 이용하여 handshake 과정을 맺는다.
SSL_connect(ssl); |
* SSL_connect 실패시 반환값 : -1
5. SSL_write 함수를 이용하여 서버에게 메시지를 암호화하여 전송하고 서버로부터 암호화된 메시지를 받는다.
const char *msg = "Hello"; |
6. SSL_read 함수를 이용하여 서버로 부터 받은 메시지를 복호화하여 확인한다.
char buf[1024]; int bytes; bytes = SSL_read(ssl, buf, sizeof(buf)); buf[bytes] = 0; printf("Received: \"%s\"\n", buf); |
7. 연결을 끊고 객체들을 제거한다.
헤더 | #include <unistd.h> |
SSL_free(ssl); close(server); |
전체코드를 보면 ~
client.cpp
#include <stdio.h>
sd = socket(PF_INET, SOCK_STREAM, 0); if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) SSL_CTX* InitCTX(void) void ShowCerts(SSL* ssl) int main() server = connectServer("127.0.0.1", 1111); SSL_set_fd(ssl, server); if ( SSL_connect(ssl) == FAIL ) |
출처 : https://m.blog.naver.com/PostView.nhn?blogId=jihye2340&logNo=220679910676&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F