이것은 HTTP, 보안 HTTP에 대한 전체 안내서의 14장에 대한 요약입니다.
HTTP는 하이퍼텍스트 전송 프로토콜
http://도메인 ←이는 도메인에 가입된 컴퓨터와 통신하고 싶지만 HTTP 프로토콜을 사용하고 싶다는 의미입니다.
사람들은 인터넷을 통해 중요한 정보를 교환합니다.
→ 기본 인증과 다른 보안 요구
그래서 HTTPS가 나왔습니다. (S는 Over Secure Socket Layer의 약자입니다.)
보안 장치를 추가했습니다.
HTTPS는
- req 및 res 데이터가 암호화됩니다.
- SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security)와 함께 HTTP 기반의 암호화된 전송 수준 보안 계층을 제공합니다.
암호화
클라이언트와 서버 간의 데이터 통신에서 데이터의 스크램블링
암호화 키
키 값에 따라 암호화 결과 값이 다릅니다.
대칭 키
- 발신자와 수신자가 동일한 키를 사용
- 인코딩과 디코딩 모두 동일한 키를 사용합니다.
- 공유 키 설정
- 대칭 키를 사용하려면 송신자와 수신자가 통신하기 전에 공유 비밀 키를 가지고 있어야 합니다.
- N개의 클라이언트가 서버를 요청하면 서버는 N개의 키를 보유해야 합니다.
- 다루기가 쉽지 않습니다. → 비대칭 키로 해결
비대칭 키 – 다른 키를 사용하여 인코딩 및 디코딩
- 암호화를 위한 공개키(클라이언트 → 서버)
- 복호화 시 비밀키(서버)
RSA – 공개 키 암호화 알고리즘
- 암호문과 공개 키에서 개인 키를 확인할 수 없도록 생성되었습니다.
- 론 아르 자형아이베스트, 아디 에스하미르, 레너드 ㅏdleman 세 사람의 성을 따서 명명되었습니다.
- RSA-2048은 전 세계 대부분의 인터넷 뱅킹에서 사용됩니다.
기타 추가 인증 수단
서명
- 암호화 시스템으로 메시지에 서명하고 변조되지 않았음을 증명합니다.
- 서명에 의한 신원 증명
디지털 인증서
- X.509 v3 표준 형식으로 정보 저장
- 웹 서버 인증서, 클라이언트 이메일 인증서, 소프트웨어 코드 서명 인증서, CA 인증서 등에 사용됩니다.
HTTPS 체계
- HTTP의 경우
- 포트 80에 연결
- HTTPS의 경우
- 포트 443에 연결
- 서버와의 핸드셰이크 – SSL 인증서 교환
HTTPS의 전송 단계
- 클라이언트는 포트 443(기본 보안 HTTP 포트)에 연결합니다.
- TCP가 연결되면 클라이언트와 서버는 SSL 계층을 초기화하고 키를 교환합니다(핸드셰이크).
- 교환된 키를 사용한 암호화 작업
- 클라이언트는 보안 계층에 요청 메시지를 보냅니다.
- TCP 연결 해제
악수
- 비밀번호 선택
- 신분증 인증
- 채널 암호화를 위한 임시 세션 키 생성
서버 인증서
- HTTPS 전송에 항상 필요
- 보안 전송, 예: 나. 신용카드 정보
- 조직의 이름, 주소, DNS 도메인 이름 및 기타 정보가 포함된 X.509 v3 파생 인증서.
사이트 인증서 확인
브라우저 인증서를 확인하는 4가지 방법
- 인증서 유효기간 확인
- 인증 기관(예: CA)의 서명 확인
- 서명 기관이 신뢰할 수 있다고 판단되면 브라우저는 서명 기관의 공개 키를 서명에 적용합니다.
- 인증서의 도메인 이름이 통신한 서버의 도메인 이름과 일치하는지 확인하십시오.
가상 호스팅 및 인증서
서버 인증서에 나열된 공식 호스트 이름이 사용자로부터 검색된 가상 호스트 이름과 일치하지 않습니다.
도메인 주소 www.naver.com 하지만 https://www.naver.com 들어갈 때
→ 리디렉션으로 해결해야 합니다.
개방형 SSL
/************************************************** *** ***************
- https_client.c — 오류 검사가 없는 매우 간단한 HTTPS 클라이언트
- 사용법: https_client 서버 이름
- ******/
#포함하다
#포함하다
void main(int argc, char **argv) { SSL *ssl; SSL_CTX *ctx; SSL_METHOD *클라이언트_방법; X509 *서버_인증서; int sd, 오류; char *str,*hostname,outbuf(4096),inbuf(4096),host_header(512); 구조체 hostent *host_entry; struct sockaddr_in server_socket_address; 구조체 in_addr ip;
/======================================/ /* (1) SSL 라이브러리 초기화 // ===========================================*/
SSLeay_add_ssl_algorithms( ); client_method = SSLv2_client_method( ); SSL_load_error_strings( ); ctx = SSL_CTX_new(클라이언트_방법);
printf(“(1) SSL 컨텍스트 초기화됨\n\n”);
/===========================================/ /* ( 2) 서버 호스트 이름을 IP 주소로 변환 /========================================== == == =*/
호스트 이름 = argv(1); host_entry = gethostbyname(호스트명); bcopy(host_entry->h_addr, &(ip.s_addr), host_entry-
h_길이);
printf(“(2) ‘%s’에는 IP 주소 ‘%s’가 있습니다.\n\n”, hostname, inet_ntoa(ip));
/============================================ / /* (3) 서버에서 포트 443으로 TCP 연결을 엽니다. //==================================== = == =============*/
sd = 소켓(AF_INET, SOCK_STREAM, 0);
memset(&server_socket_address, ‘\0’, sizeof(server_socket_address)); server_socket_address.sin_family = AF_INET; server_socket_address.sin_port = htons(443); memcpy(&(server_socket_address.sin_addr.s_addr), host_entry->h_addr, host_entry->h_length);
err = connect(sd, (struct sockaddr*) &server_socket_address, sizeof(server_socket_address)); if (err < 0) { perror("서버 포트에 연결할 수 없습니다."); 출구(1); }
printf(“(3) 호스트 ‘%s’, 포트 %d\n\n”, hostname, server_socket_address.sin_port에 대한 TCP 연결이 열려 있습니다.
/*=================================================== ===== / / (4) TCP 연결을 통해 SSL 핸드셰이크 시작 */
/=============================================== ====/
ssl = SSL_new(ctx); /* SSL 스택 엔드포인트 생성 / SSL_set_fd(ssl, sd); / SSL 스택을 소켓에 연결 / err = SSL_connect(ssl); /SSL 핸드셰이크 시작 */
printf(“(4) SSL 엔드포인트 생성 및 핸드셰이크 완료\n\n”);
/===========================================/ /* (5 ) /에서 협상된 암호 /======================================= =****/
printf(“(5) 암호에 연결된 SSL: %s\n\n”, SSL_get_cipher(ssl));
/======================================/ /* (6) 서버 인증서 출력 / / ===========================================*/
server_cert = SSL_get_peer_certificate(ssl);
printf(“(6) 서버의 인증서를 받았습니다:\n\n”);
str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0); printf(” 제목: %s\n”, str);
str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0); printf(” 발급자: %s\n\n”, str);
/* 여기에서 인증서 유효성 검사가 수행됩니다 */
X509_free(서버_인증서);
/************************************************** *** *** ******** / /* (7) 핸드셰이크 완료 — SSL을 통해 HTTP 요청 보내기 */
/************************************************** *** ***********/
sprintf(host_header,”호스트: %s:443\r\n”,hostname); strcpy(outbuf,”GET/HTTP/1.0\r\n”); strcat(outbuf,host_header); strcat(outbuf,”연결: 닫기\r\n”); strcat(outbuf,”\r\n”);
오류 = SSL_write(ssl, outbuf, strlen(outbuf)); 종료(SD, 1); /* EOF를 서버로 전송 */
printf(“(7) 암호화된 채널을 통해 보낸 HTTP 요청:\n\n%s\n”,outbuf);
// /* (8) SSL 스택에서 HTTP 응답 다시 읽기 */ //
오류 = SSL_read(ssl, inbuf, sizeof(inbuf) – 1); inbuf(오류) = ‘\0’; printf (“(8) 반환된 %d 바이트의 HTTP 응답:\n\n%s\n”,err,inbuf);
/// (9) 완료되었으므로 연결을 닫고 정리합니다. ///
SSL_shutdown(ssl); 닫기(sd); SSL_free(ssl); SSL_CTX_free(ctx);
printf(“(9) 완료, 정리 및 종료\n\n”);
섹션별로 프로그램 섹션을 살펴보겠습니다.
- 프로그램의 맨 위에는 TCP 네트워크와 SSL을 지원하는 데 필요한 지원 파일이 있습니다.
- 섹션 1은 핸드셰이크 매개변수 및 기타 정보를 추적하기 위해 로컬 컨텍스트를 생성합니다.
SSL_CTX_new를 호출하여 SSL 연결 상태를 확인하십시오.
- 섹션 2는 입력된 호스트 이름(명령줄 인수로 제공됨)을 IP로 변환합니다.
이름으로 Unix gethost 기능이 있는 주소. 다른 플랫폼에는 다음과 같은 다른 방법이 있을 수 있습니다.
이 시설을 제공합니다.
- 섹션 3은 서버의 포트 443에 대한 TCP 연결을 여는 로컬 소켓을 만듭니다.
원격 주소 정보를 업데이트하고 원격 서버에 연결합니다.
- TCP 연결이 설정되면 SSL 계층을 TCP 연결에 연결합니다.
SSL_new 및 SSL_set_fd를 사용하여 서버와 SSL 핸드셰이크
SSL_연결. 섹션 4를 완료하면 다음과 같이 작동하는 SSL 채널이 설정됩니다.
암호를 선택하고 인증서를 교환했습니다.
- 섹션 5는 선택한 대량 암호화 키의 값을 반환합니다.
- 섹션 6은 전송된 X.509 인증서에 포함된 일부 정보를 출력합니다.
인증서 소유자 및 인증서를 발급한 조직에 대한 정보가 포함된 서버입니다.
했다. OpenSSL 라이브러리는 내부 정보로 특별한 작업을 수행하지 않습니다.
서버 인증서. 웹 브라우저와 같은 실제 SSL 애플리케이션은 미쳤습니다.
인증서가 올바르게 서명되었고 올바른 호스트에서 발급되었는지 확인하십시오. 우리
14.7.6은 브라우저가 서버 인증서로 수행하는 작업을 설명합니다.
- 이 시점에서 안전한 데이터 전송을 위해 SSL 연결을 사용할 수 있습니다. 7절에서 우리는
SSL_write를 사용하여 SSL 채널을 통해 간단한 HTTP 요청 “GET/HTTP/1.0″을 보냅니다.
그런 다음 연결의 나가는 절반이 닫힙니다.
- 섹션 8은 SSL_read를 사용하여 연결에서 응답을 읽고 반환합니다.
화면. SSL 계층이 모든 암호화 및 복호화를 처리하므로 이를 수행할 수 있습니다.
일반 HTTP 명령을 쓰고 읽습니다.
- 마지막으로 섹션 9에서 청소합니다.
프록시를 통한 보안 트래픽 터널링
암호화를 위해 프록시 서버를 사용하는 문제
→ 프록시는 공개 키로 암호화된 헤더 데이터를 읽을 수 없습니다.
HTTPS SSL 터널링 프로토콜해결
- 클라이언트는 먼저 연결하려는 호스트와 포트를 프록시에 알립니다.
- 이것은 암호화가 시작되기 전에 프록시가 이 정보를 읽을 수 있도록 일반 텍스트로 수행됩니다.
- HTTP는 CONNECT라는 새로운 확장 방법을 사용하여 일반 텍스트 끝점 정보를 보내는 데 사용됩니다.
- CONNECT는 연결이 설정되면 클라이언트와 서버 간에 직접 원하는 호스트 및 포트 번호와 터널 데이터에 대한 연결을 열도록 프록시에 지시합니다.
- CONNECT 방법은 보안 원본 서버의 호스트 이름과 포트를 콜론(:)으로 구분하여 제공하는 한 줄 텍스트 명령입니다.
- host:port 다음에는 공백, HTTP 버전, CRLF 다음에는 0개 이상의 HTTP 요청 헤더 행과 빈 행이 옵니다. 빈 라인 이후에 연결을 설정하기 위한 핸드셰이크가 성공하면 SSL 데이터 전송을 시작할 수 있습니다.
- 프록시는 요청이 유효하고 사용자에게 연결 권한이 있는지 확인한 다음 res 200을 반환합니다.