웹 브라우저에서 인증서를 실제로 검증하는지 검사해 보려면 MITM을 하거나
가짜 인증서와 서버를 만들어 보면 됩니다. 여기서는 후자를 해봅니다.
먼저 패킷을 캡처한 것에서 Certificate를 누르고 ctrl+H 눌러서 빼옵니다.
다 빼내오면 rootCA가 있고
마지막에 demo.labs.mastercard.com을 사이닝 해주는 것을 알 수 있습니다.
저는 중간과정 생략하고 데모 인증서와 rootCA 인증서만 가짜로 만들어 보았습니다.
일단 key를 만듭니다. 키 길이는 인증서를 보고 맞춰줍니다.
openssl genrsa 2048 > my.key
root의 key는 특별히 암호도 걸어주었습니다.
openssl genrsa -aes128 2048 > root.key
OPENSSL_CONF 값이 없으면 Unable to load config info from 에러가 납니다.
(시스템 환경변수로 추가해도 됩니다.)
set OPENSSL_CONF=C:\Program Files (x86)\GnuWin32\share\openssl.cnf
본래 인증서를 잘 보고 인증을 요청하는 csr 파일을 그대로 만듭니다.
( / 같은 특수문자는 앞에 escape 문자 \ 를 붙여줍니다.)
openssl req -new -key root.key -nodes -subj "/C=US/O=Entrust, Inc./OU=www.entrust.net\/CPS is incorporated by reference/OU=(c) 2006 Entrust, Inc./CN=Entrust Root Certification Authority" -out CA-CA.csr
만든 csr을 셀프 사이닝 해줍니다.
openssl x509 -req -days 365 -in CA-CA.csr -signkey root.key -out CA-CA.crt
이제 생성되었습니다. 똑같아 보이지만, 오른쪽이 진짜, 왼쪽이 가짜인증서입니다.
이제 똑같은 방식으로 서버용 키를 만들고 키로 csr파일 만들고,
rootCA로 사인해 주면 됩니다.
아까 키는 만들었었죠.
openssl genrsa 2048 > my.key
인증서를 잘 보고 csr파일을 만들어 줍니다.
openssl req -new -key my.key -nodes -subj "/C=BE/L=Waterloo/O=MasterCard International Incorporated/OU=NS01 ISF/CN=demo.labs.mastercard.com" -out demo.csr
(CN은 본인의 도메인으로 맞춰 줘야 관련 에러가 나지 않습니다.)
이제 rootCA인증서로 csr파일을 사인해 주면 됩니다.
openssl x509 -req -days 500 -in demo.csr -CA CA-CA.crt -CAkey root.key -CAcreateserial -out my.crt
그럼 아래처럼 2단계로 인증하는 가짜인증서 체인을 만들 수 있습니다.
물론 지금 했던 과정은 공개된 인증서를 바탕으로 하는 것이기 때문에
크게 문제될 것은 없습니다. 어차피 RSA2048 은 현재 깰 수 없을 것이기 때문이죠.
그리고 지금 위와 같이 인증서를 만들었다면, SHA1 으로 되어있을 텐데요,
획기적인 해시 충돌 취약점이 발견되서 모두들 SHA256 으로 바꾸도록 하고있으니
설정을 통해 SHA256 으로 바꿔주는게 좋겠습니다. ( -sha256 옵션 추가 )
이제 서버를 올려줍니다. 저는 간단하게 Node.js 를 사용했습니다.
HTTPS and HTTP Server
var http=require('http'), https = require('https'), express = require('express'), fs = require('fs'); var options = { key: fs.readFileSync('my.key'), cert: fs.readFileSync('my.crt') }; var port1 = 80; var port2 = 443; var app = express(); http.createServer(app).listen(port1, function(){ console.log("Http server listening on port " + port1); }); https.createServer(options, app).listen(port2, function(){ console.log("Https server listening on port " + port2); }); app.get('/', function (req, res) { res.writeHead(200, {'Content-Type' : 'text/html'}); res.write(''); res.end(); }) app.post('/login', function (req, res){ var userId = req.param("userId"); var password = req.param("password") res.writeHead(200, {'Content-Type': 'text/html'}); res.write(userId+', you are now logged in.'); res.write(' back home'); res.end(); });Welcome
'); res.write('Please login'); res.end(); }); app.get('/login', function (req, res){ res.writeHead(200, {'Content-Type': 'text/html'}); res.write('Login
'); res.write('
자 이제 접속 해보면 아래와 같이 나오는게 정상입니다.
0 개의 댓글:
댓글 쓰기