04 · 같은 로그인, 다른 전송
같은 가짜 로그인으로 HTTP와 HTTPS를 비교하고 인증서의 역할을 찾습니다.
오늘 하나만: 서버가 읽을 수 있는 것과, 가는 길에서 읽을 수 있는 것은 다르다.
03의 가짜 로그인은 비밀번호가 화면에서 가려져도 HTTP 본문에서 읽혔습니다. 이번에는 같은 공개값을 HTTPS로 보냅니다. 폴더 하나를 하루에 끝낼 필요는 없습니다.
1. 예상하기
HTTPS로 바꾸면 어느 곳에서 비밀번호가 안 보일까요?
| 관찰 위치 | 내 예상 | 실행 뒤 확인 |
|---|---|---|
| 비밀번호를 보낸 프로그램 | ||
| 중간에서 캡처한 통신 | ||
| 비밀번호를 비교하는 서버 |
2. 내 컴퓨터에 실험 준비
04-HTTPS와보안 폴더를 엽니다. Node.js와 OpenSSL 준비는 교사와 확인합니다. 03의 로그인 서버가 켜져 있다면 먼저 종료합니다.
npm run cert:setup
npm run login:compare첫 명령은 짧게 사용하는 수업용 인증서를 만듭니다. 두 번째 명령은 같은 가짜 로그인 처리를 HTTP 8083, HTTPS 8443에서 실행합니다. 인증서는 2일간 유효하며, 이미 .certs가 있거나 날짜가 지났다면 교사와 재발급합니다.
http://127.0.0.1:8083에서는 앞 수업과 같은 폼을 볼 수 있습니다. 브라우저는 수업용 CA를 원래 알지 못하므로 HTTPS 주소에서 경고가 날 수 있습니다. 경고를 무시하고 통과하지 말고 다음의 준비된 클라이언트로 비교합니다.
3. 같은 요청 두 번 보내기
다른 터미널에서도 04 폴더를 열고 실행합니다.
npm run login:client -- http://127.0.0.1:8083 demo01
npm run login:client -- https://127.0.0.1:8443 demo01둘 다 HTTP status: 200과 Demo accepted가 나오는지 확인합니다. 클라이언트는 공개 비밀번호 class-demo-123만 보냅니다. 다른 실제 비밀번호를 넣는 기능은 없습니다.
선택 변경: HTTPS가 성공·실패를 바꾸는 기능인지 확인합니다.
npm run login:client -- https://127.0.0.1:8443 demo01 --wrong암호화해 보냈지만 가짜 비밀번호가 틀렸으므로 HTTP status: 401과 Demo rejected가 나옵니다.
4. Wireshark에서 비교
- 내 컴퓨터에서 실험하므로 루프백 인터페이스를 선택합니다.
- 표시 필터
tcp.port == 8083 || tcp.port == 8443을 적용합니다. - 캡처를 시작한 뒤 3번의 두 요청을 다시 보냅니다.
- 8083 통신의 Follow → TCP Stream에서
POST /login본문을 찾습니다. - 8443 통신을 선택해 TCP Stream을 비교합니다. TLS의 암호화된 데이터에서는 같은 본문을 읽을 수 없습니다.
HTTP: username=demo01&password=class-demo-123
HTTPS: 같은 HTTP 내용이 TLS로 보호되어 전송됨복호화 키를 제공하지 않은 캡처로 비교합니다. 캡처 파일이 없으면 교사 화면에서 자신의 요청을 찾아도 됩니다. 단순히 “HTTPS 패킷에 읽을 수 있는 문자가 하나도 없다”로 판단하지 않습니다. IP·포트 등 통신 정보는 여전히 보입니다.
5. 서버는 어떻게 읽었을까?
HTTPS 서버의 TLS 처리가 복호화한 뒤 HTTP 요청을 프로그램에 전달합니다. 그래서 HTTP와 HTTPS는 같은 handleLogin 함수에서 가짜 비밀번호를 비교합니다.
- 브라우저 개발자 도구는 보내기 전·받은 뒤의 내용을 볼 수 있습니다.
- 서버도 받은 내용을 읽을 수 있습니다.
- HTTPS가 보호하는 것은 전송 구간입니다. 저장된 비밀번호와 권한 검사는 별도입니다.
6. 인증서는 왜 필요할까?
클라이언트 코드의 ca는 “이번 실습에서 이 발급자를 신뢰한다”는 지정입니다. Node는 인증서의 유효성과 접속한 이름/IP가 인증서에 있는지도 검사합니다. 암호화만 하고 상대 확인을 생략하는 것과 다릅니다.
교사가 안내하는 브라우저 인증서 화면에서 대상 이름, 발급자, 유효기간을 찾아봅니다. 인증서가 있다는 사실만으로 그 서비스의 모든 동작이 안전해지는 것은 아닙니다.
선택: 교사 서버로 보내기
교사가 **공개 인증서 teacher-ca-cert.pem**을 전달하면 04 폴더에 둡니다. ca-key.pem, server-key.pem 같은 개인키는 받거나 나누지 않습니다.
npm run login:client -- https://교사IP:8443 demo01 --ca=teacher-ca-cert.pem교사IP는 실제 주소로 바꾸고 학생별 demo01~demo05를 사용합니다. 자신의 cert:setup으로 만든 CA는 교사 CA와 다른 것이므로 대신 사용할 수 없습니다.
설명하고 마치기
**“같은 로그인 결과인데 HTTP는 본문을 읽을 수 있고, HTTPS는 중간 캡처에서 읽을 수 없다. 서버와 브라우저는 여전히 읽을 수 있다.”**를 자신의 관찰과 연결해 설명하면 성공입니다.
다음 질문: 서버에 비밀번호를 저장할 때는? 다음 요청에서도 나를 기억하려면? 다른 사람의 기록을 열면? 이 세 가지는 07 인증·권한에서 이어갑니다.