포럼
SSL을 대신할 Javascript/RSA/AES 아이디어 + 데모 + 미완성Addon
2014.04.08 02:22
- 개요 -
SSL을 대신하여 간단한 아이디어를 제시해 봅니다.)
Javascript (jQuery) + AES + RSA 를 이용한 클라이언트→서버로의 단방향 form 암호화 입니다.
Hybrid 암호화(RSA + AES) 를 이용하여 단순 RSA만을 사용하는것보다 속도가 빠릅니다.
RSA : 1024bit
AES : 128bit CBC mode 를 이용하였으며, 중소규모 사이트의 보안 향상을 위하여 고안하였습니다.
보안 강도 : 저 RSA+AES 중 하나를 1년내에 어떻게 든 깨시면 제가 커피사드립니다.^^
- 원리 및 과정 -
1. 서버쪽에서 Javascript 변수로 RSA public key를 쏴줍니다.
(RSA key는 성능을 위하여 웹사이트 전체에 걸쳐서 addon 설치시 개발자가 딱 한번 만들어 두고 동일한 key를 계속 사용합니다. 혹은 1일,1주일 등의 단위로 자동으로 적절히 바꾸는 방법이 있겠지요.)
2. 클라이언트에서 폼을 submit 할때 자바스크립트(j Query)로 해당폼을 가로챕니다.
2-1) 30글자의 랜덤한 TEXT를 만들고(이하 AES_KEY라고 합니다.) 그 AES_KEY를 javascript로
RSA Public_key로 암호화 합니다.(일단은 30글자, 나중에는 100글자를 사용하면 좋을것 같습니다.)
2-2) form에다 dynamic 하게 hidden input을 생성하고 해당칸에 RSA로 암호화한 AES_KEY를 넣습니다.
2-3) 모든 input 내용을 AES로 암호화 힌 후 내용을 대체합니다.
2-4) 이제 클라이언트에서 전송합니다.
3. 서버에서 받은후 해독합니다.(addon)
3-1) 서버에서 RSA로 암호화된 AES_KEY를 받은뒤에 서버에 저장된 RSA Private_key로 풀어줍니다.
3-2) 해독한 AES_KEY로 나머지 폼들($_POST, $_GET)들을 전부다 풀어줍니다.
- 장점 및 단점 -
이 방법의 단점 으로는
- Javascript 미지원 브라우저에서는 평문으로 전송된다는 것.
- form이 아닌 정보는 모두 plain text로 날라간다는것
- 클라이언트→서버 단방향 암호화 라는 것
- 그리고 세션쿠기가 그대로 날라간다는 취약점이 있다는 것이지요(이거는 SSL 밖에 답이 없을것 같네요.)
그러나 복잡한 SSL을 addon 하나로 매우 간단하게 끝내주기에, 수많은 사이트를 관리/개발 분들에게 편리하겠지요.
일단 관리면에서 1년에 3천원 짜리 호스팅에 도메인도 수시로 바꾸는 환경이라면 SSL을 설치하기가 매우 귀찮지요. 거기에 SSL은 1년마다 도메인별로 비용도 들고, 설치도 조금 난이도가 있고, 갱신도 지속적으로 해야 하기요. 그러나 이 방법은 한번 설치하면 OK이고 addon 설치 한번으로추가비용 없이 경제성 대비 뛰어난 보안을 유지 할 수 있겠지요.
또한 많은 sub domain을 이용하여 웹사이트를 운영하신다면 SSL 설치비용을 절대로 무시하지 못하지요.
또한 로그인, 회원가입시 모든 폼을 자동으로 암호화 해 주니 로그인/회원가입시만 SSL을 사용한다면 SSL대비 보안 강도는 큰 차이가 없을것 같네요.
암튼 1줄요약하면, 보안성 대비 매우 경제적이다 정도가 될것 같습니다.
- 구현 및 데모, 실패 -
정상적으로 작동하는 demo stie (소스보기를 클릭하시면 RSA_n RSA_e로 구성된 RSA public key를 보실 수 있습니다.)
(개발자의 편의를 위해 hidden input을 사용하지 않았습니다.)
http://first.wifi.olieh.com/demo/client.php
출력결과는
0. RSA로 decrypt한 AES_key
1. AES 암호화된 ID
2. AES 암호화된 PW
3. 제출버튼 (input type이 submt image file은 암호화X)
4. RSA로 암호화된 AES_key
5. 암호풀린 ID
6. 암호풀린 PW
//RSAkey 생성기 입니다. 애드온 설치시 관리자가 직접 실행하고, 삭제하면 되나, demo를 위해 열어두었습니다.
http://first.wifi.olieh.com/demo/RSA.key.generator.php
사용한 library는
movable type aes.php aes.js
http://www.movable-type.co.uk/scripts/aes.html
http://www.movable-type.co.uk/scripts/aes-php.html
License : CCL 3.0 BY
phpseclib : RSA 서버단에서 key생성 및 decrypt
http://phpseclib.sourceforge.net/
License : MIT
php reCaptcha
https://developers.google.com/recaptcha/docs/php
License : 자체라이센스(MIT + 반드시 라이센스 첨부 필수)
RSA and ECC in JavaScript
http://www-cs-students.stanford.edu/~tjw/jsbn/
License : BSD
차후 개선 여지는
1. php AES library를 조금 더 빠른것을 사용하는 방법이 있을것 같습니다. 다만 php 와 aes에서 둘다 호환이 가능해야 할것 같습니다. crypto.js 와 phpseclib의 AES를 사용하는것을 시도했는데 잘 하지 못했습니다. 그런데 이렇게 속도문제로 개선해야 할정도의 사이트이면 SSL을 사용하는것이 답이라고 생각합니다.
(phpseclib의 AES는 openssl과 연계되어 현재 적용된 AES lib보다 20배 정도 빠르다고 합니다. 다만 이거에 맞는 js lib를 찾지 못하였습니다.)
2. 클라이언트 상의 jquery에서 현재는 현재 입력한 input form을 지우고 암호화 시킨 문자열을 그냥 넣어버려서 end user가 암호화된문자열은 그냥 보게되지만, 차후에는 input text form의 갯수만큼, hidden form을 dynamic 하게 만들고 추가한 hidden form에 암호화 된 문자열을 집어넣은뒤에, 일반 text form의 내용은 지워서 일반 사용자(비개발자)가 깔끔하게 볼 수 있으면 좋을듯 합니다.
3. asymetric 암호화의 경우 RSA가 아닌 ECC암호화가 더 빠르다고 하는데, 쓸만한 library를 찾아 보지 못했습니다. 영문위키상으로는 RSA 3072bit = ECC 384bit 정도의 강도 라고 하네요.
내용추가 : ECC는 특허가 걸려서 힘들것 같네요.ㅠㅠ 그래서 lib도 없는것 같아요.
미완성된 addon (이름: SSLPLS) 및 정상적인 demo는 LGPLv2 로 배포합니다.
SSLPLS는 SSL Please의 약자이며 가능하면 SSL을 적용해주세요. 라는 뜻입니다.
댓글 19
-
GG
2014.04.08 02:30
-
AJKJ
2014.04.08 02:34
$_post, $_get 변수에서 암호화된 text를 추출 한뒤에 복호화 한 것을 덮어 씌우면 되지 않을까요?
addon 상에서는 암호화가 아닌 복호화만 하는것이라, 별도의 모듈이 필요 없다고 생각했습니다.
서버→클라인언트는 비 암호화, 클라이언트→서버에서 form만 암호화 입니다.
-
GG
2014.04.08 02:36
말씀하시는것은 외부페이지로 뭔가 구현하였을때는 가능해 보이지만,
실제로 암호화가 필요한 회원가입/로그인 등의 과정은 외부페이지로 구현한 것이 아닙니다.
member 모듈 작동에 간섭해야 하는데, 이를 애드온 만으로 해결해 보고자 한다면 많은 고민이 필요할 것으로 보입니다.
-
AJKJ
2014.04.08 02:46
정말 죄송하지만, 제가 초보라서 잘 이해를 못하겠습니다. 조금 자세히 설명해 주시면 정말 감사하겠습니다.
1. 저는 XE에 적용해 보았을때, 폼을 암호화 하는 jquery가 작동하지 않았는데, 그것 때문에 module을 건드리거나 새로 만들어야 하는지 궁금합니다.
2. 그리고 module 실행전 복호화한 text를 $_get, $post 변수에 덮어 씌우는데 이러한 경우 어떠한 문제가 될 수 있는지 알려주시면 점말 감사하겠습니다.
-
GG
2014.04.08 02:54
제가 더 초보입니다 ㅡ.ㅡ;
1. jquery 의 경우 문법이 좀 다릅니다. 아마 그래서 에러가 났던것 같습니다.
jQuery(function($) {});
형태로 해야 할 듯 합니다.
2. 잘 되는지 안되는지 테스트를 안해보았습니다. 아마 잘 되리라 생각되지만 혹시라도 안된다면, '모듈 실행전' 이라는 부분에서 지금은 컨텐츠 보여지기 직전 시점에 작동하도록 애드온이 짜여져 있는데 이부분을 before_module_init 혹은 before_module_proc 등으로 해보시는건 어떠신지.. 생각만 해봅니다. 잘 되시면 무시하셔도 됩니다 ㅡ.ㅡ;
-
AJKJ
2014.04.08 19:10
수정했는데도, 일단 jQuery가 먹히지 않으니 답답하네요. function 내의 변수가 전혀 실행이 안되요ㅠㅠ
일단 개발용 사이트 하나 만들어 봐야 겠습니다.
-
GG
2014.04.08 02:39
아 그게 아니군요.
지금 소스를 보니 if(!defined("__ZBXE__")) exit(); 이렇게 하면 최신 버전에서 안먹힙니다.
if(!defined("__XE__")) exit();
로 수정 바랍니다.
-
AJKJ
2014.04.08 02:48
수정하였습니다. 감사합니다.^^
-
GG
2014.04.08 02:40
다시 잘 생각해 보니 말씀하신 형태로 잘 되지 않을까 싶습니다.
제가 무지해서 그런거니 양해 바랍니다.
-
teguh100
2014.04.08 04:01
-
기진곰
2014.04.09 13:39
굳이 RSA+AES를 깰 필요 있나요?
1단계에서 서버가 클라이언트에게 전송하는 공개키는 SSL 없이 완전 평문 상태이므로
이것을 공격자가 가로채서 자신의 공개키로 치환해 버리면 게임 오버입니다.
나중에 클라이언트가 전송하는 데이터는 공격자의 공개키로 암호화되어 있을 테니
이것을 가로채서 공격자 자신의 개인키로 복호화하여 내용을 파악한 후,
아까 가로챘던 서버의 공개키로 다시 암호화하여 서버로 보내주면
서버와 클라이언트는 방금 중간자 공격을 당했다는 사실조차 모르게 됩니다.
-
LI-NA
2014.04.09 17:49
뭐 그건 SSL도 같은 취약점이죠 ㅎㅎ;;
멘 처음 암호화 키 교환을 가로 채는거...
-
기진곰
2014.04.09 20:44
알고리듬적인 측면만 보면 SSL(TLS)도 키 교환을 가로챌 여지가 있습니다만,
현실적으로는 그걸 막기 위해 CA라는 것이 있습니다.
CA가 서명하지 않은 인증서는 경고창을 띄우도록 되어 있기 때문에
공격자가 자신의 키로 바꿔치기할 수 없습니다.
예전 IE6 시절과 달리, 요즘은 경고창을 무시하는 것도 아주 어렵게 되어 있어요.
-
AJKJ
2014.04.09 18:30
중간자 공격까지 방어는 생각 하지 않고있습니다. SSL 외에는 중간자 공격을 막을 방법은 없다고 생각합니다.
이 아이디어는, 경제적이고 간편한 방법으로 최소한의 기초적인 스니핑에 당하지 말자'라는 모토에서 만들어 보고 있습니다.
흔히 보안이 안된 스타벅스 무선랜 정도에서도 안전하게 사용 할 수 있도록이요.
-
기진곰
2014.04.09 20:39
네, 중간에 패킷을 변조할 능력이 없는 기초적인 스니핑 기법이라면 방어할 수 있겠습니다. 그러나 요새 SSL 때문에 워낙 말이 많아서 모두들 공짜로 쓸 수 있는 대안을 찾고 있는 상황이라, 혹시라도 SSL과 같은 효과가 있는 것으로 오해하는 분이 있을까 걱정이 됩니다. 반드시 SSL을 써야 하는 곳에 님의 애드온을 썼다가 법적인 문제에 휘말리는 사람이 나올 수도 있어요.
-
LI-NA
2014.04.09 17:56
흠.. 일단 XE에서 모든 폼에 자바스크립트가 이미 바인딩 되어있습니다.
그것때문일지도 모르겠네요... XE 자바스크립트가 예상 외로 복잡해서요...;;
그리고 방식은 살펴봐야겠네요.
모듈 로딩 전에 모든 GET POST 변수를 싹 다 Context나 obj로 보내버리는지.. 아닌지...
일단 POST 변수를 가로 채는건 괜찮을 것 같기도 합니다. 누가 뭐래도 모듈 로딩 전 - 이니 말이죠...
-
AJKJ
2014.04.09 18:31
삽질해서 jQuery 부분은 해결한뒤에 이 글을 보네요.ㅠㅠ 그 부분을 해결했습니다. xml filter.js 부분에 뭔가가 있더군요.
그로인해 단순 애드온 설치로만 해결볼 부분은 아닌것 같습니다. XE core에 약간의 수정이 필요합니다.
다만 ./common/js/xml_filter.js에 사용자가 직접 한줄정도의 코드를 추가해야 할듯 합니다.
그리고 일단 jquery 외에도, 지금 몇가지 문제가 있어서 손을 보고 있습니다만, 범용으로 만들려면 쉽지 않을것 같습니다.
파일 업로드, 이미지 업로드, 등도 고려해야 하고, XE는 로그인이 mid, act 가 전부 form으로 날라가는지라, 이것까지 암호화 하기는 힘들것 같습니다.(뭐 전부 암호화 하려면 애드온이 아닌 index.php 최상단에서 암호를 풀어주는 방법 밖에는 없을것 같네요.)
일단은 로그인/회원가입 addon이라도 대충 데모가 완성되면 공개하겠습니다.
현재는 뒤죽박죽이라서 배포하기가 너무 곤란하네요..
-
AJKJ
2014.04.09 18:42
아 그리고, 지금 데모사이트가 조금 말썽입니다...
일단 몇일내로 대충 수정하여 draft addon을 공개해 볼게요.
-
AJKJ
2014.04.10 02:47
http://www.xpressengine.com/userForum/22678881 70% 완성했습니다. 로그인, 회원가입 보안은 됩니다.
암호를 해석해서 컨트롤 하는 부분 때문에 애드온 + 모듈 형태로 가야 하지 않을까 생각만 해 봅니다.
즉, 애드온으로 암호화 하는 부분을 해결하고, 특정 모듈로 일괄 향하게 한 다음
모듈에서 복호화 한 다음 실제로 암호화된 데이터가 향해야 하는 procXXXXXX 같은 act 부분을한번 더 redirect 하는
그런 기능이 되어야 하지 않을까... 그냥 상.상. 만 해 봅니다 :)