테스트 사이트 - 개발 중인 베타 버전입니다

OpenSSL for Http-보안서버기능을 하는 암호화 프로그램

· 12년 전 · 20284 · 41
http_openssl.gif
#### OpenSSL for Http는 G4S가 나온지 별로 안되었을 때 공개하였으나 지금 G4S는 베타버젼이 32까지 왔습니다. 따라서 아래 소스 수정 방법이 최신 버젼과는 맞지 않을 수 있습니다. ####

약속한 대로 http_openssl을 공개합니다. 최근 출시된 그누보드 G4S용입니다.

잘 읽고 따라서 하셔야 합니다.

프로그램이 맘에 들면 기부를 생각해보세요. 기부 구좌는 DONATION.txt에 있습니다.


========================================================
http_openssl(OpenSSL for Http based on PHP & JavaScript)
========================================================


일반적으로 서버와 클라이언트 간 정보교환은 쉽게 탈취될 수 있습니다.
이런 까닭에 개인정보와 관련된 부분에서 보안 서버를 사용해야 할 필요를 발견하게 됩니다.
문제는 보안 서버를 유지하는 비용이 지속적으로 들어간다는데 있습니다.
개인 홈페이지의 경우 호스팅 비용외 추가적으로 들어가는 비용 역시 적지 않은 금액으로 여겨집니다.

저렴한 보안 서버의 경우 OpenSSL을 이용합니다. 아파치 서버의 경우 대부분 그렇습니다.
보안 서버로 연결하게 되면 일반적인 http로 접속이 되는 것이 아니라 https로 접속이 되어 보안서버임을 알립니다.

그렇다면 OpenSSL을 보안 서버가 아닌 일반 서버에서 구동되게 하면 어떨까? 하는 생각을 하게 됩니다.
이미 PHP로 작성된 웹 애플리케이션이 존재하기 때문에 그런 생각을 더 갖게 합니다. 예로 PHPSeculib이 그 중 하나입니다.

문제는 보안 서버를 사용하지 않고 클라이언트와 서버간 정보를 암호화하여 주고 받으려면
적어도 Javascript와 PHP로 구동 가능해야 합니다.
그런데 현재 인터넷에서 찾을 수 있는 모든 자료들은 PHP와 Javascript를 동시에 구동하는 프로그램이 많지 않으며
또한 그 효용도도 떨어진다는 것을 발견하게 됩니다. 그런 이유로 본 프로젝트를 시작하게 되었습니다.

OpenSSL for HTTP은 클라이언트에서는 Javascript로 서버에서는 PHP로 구동되는 프로그램으로
보안 서버와 거의 비슷한 기능을 합니다.

OpenSSL for HTTP은 다음과 같은 원리로 작동합니다. 이것은 한 예입니다:

1. 클라이언트에서 서버로 보안 페이지 접근
2. 서버에서 보안 페이지를 전송하면서 RSA 비대칭키인 public key를 제공한다.
3. 클라이언트 브라우저에서 서버와 상호간 사용할 AES(CBC모드) 대칭키를 생성한 후,
이 키를 제공받은 RSA public key로 암호화한다.
4. 클라이언트에서 전송 전 모든 데이터를 생성된 AES(CBC모드) 대칭키로 암호화 한 후,
3.번에서 RSA public key로 암호화한 값과 같이 전송한다.
대칭키는 클라이언트에는 로그아웃할 때까지 쿠키로 저장한다.(이 대칭키 값은 보안 페이지 접속시 변할 수 있다.)
5. 서버에서 전송받은 데이터 중 RSA public key로 암호화된 대칭키를 RSA private key로 복호화 한 후,
복호화한 대칭키를 이용해 나머지 데이터를 복호화하여 저장한다. 복호화한 대칭키는 필요한 경우 아니면 세션 저장하지 않는다.


OpenSSL for HTTP이 여러분에게 많은 유익이 되었다면 기부(donation)를 하는 건 어떤가요?
그렇다면 업그레이드 및 새로운 프로그램 개발에 도움이 될 겁니다.
기부(donation)를 하려면 DONATION.txt를 보면 구좌가 있습니다. 액수는 따지지 않습니다.


=====================
OpenSSL for HTTP 설치
=====================

파일을 수정할 때 먼저 코드를 찾아 그 코드의 앞이나 뒤에 붙여넣거나 찾은 코드를 교체해야 한다.
따라서 설치방법을 읽을 때 찾은 코드의 "앞" 혹은 "뒤"인지를 확인하며, 또 "교체"인지 "추가"인지를 숙지한다.

1.파일복사
----------

첨부한 압축파일을 그누보드 g4s가 설치된 lib폴더에 폴더째 넣는다. 그렇게 해서 lib 안에 http_openssl이란 폴더가 있고
그 안에 파일들이 있는 구조가 되어야 한다.


2. common.php 를 연다.
----------------------

약 202 라인에서 다음 코드를 찾는다.
[code]
// QUERY_STRING
$qstr = '';
[/code]

찾은 코드 "앞"에 다음의 코드를 "추가"한다.
[code]

//==============================================================================
// http_openssl
//------------------------------------------------------------------------------
include_once G4_LIB_PATH.'/http_openssl/http_openssl.lib.php';
// http_openssl 실행
http_openssl_load();
//==============================================================================

[/code]

3. skin/member/basic/login.skin.php를 연다.
-------------------------------------------

다음의 코드를 찾는다.
[code]
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
[/code]

찾은 코드 "뒤"에 다음의 코드를 "추가"한다.
[code]

http_openssl_simple_prepare();

[/code]

다음의 코드를 찾는다.
[code]
function flogin_submit(f)
{
return true;
}
[/code]

이 코드를 다음으로 "교체"한다.
[code]
function flogin_submit(f)
{

<?php http_openssl_js_form_submit('f'); ?>

}
[/code]


4. skin/member/basic/member_confirm.skin.php를 연다.
----------------------------------------------------

다음의 코드를 찾는다.
[code]
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
[/code]

찾은 코드 "뒤"에 다음의 코드를 "추가"한다.
[code]

http_openssl_simple_prepare(true);

[/code]

다음의 코드를 찾는다.
[code]
f.action = "<?=$url?>";
return true;
[/code]

이 코드를 다음으로 "교체"한다.
[code]
f.action = "<?=$url?>";

<?php http_openssl_js_form_submit('f'); ?>

[/code]


5. skin/member/basic/register_form.skin.php 를 연다.
----------------------------------------------------

다음의 코드를 찾는다.
[code]
<form name="fregisterform" id="fregisterform" action="<?=$register_action_url?>" onsubmit="return fregisterform_submit(this);" method="post" enctype="multipart/form-data" autocomplete="off">
[/code]

찾은 코드 "앞"에 다음의 코드를 "추가"한다.
[code]

<?php

http_openssl_prepare('w', 'u',
array('mb_id', 'mb_nick', 'mb_name', 'mb_email', 'mb_birth',
'mb_homepage', 'mb_tel', 'mb_hp', 'mb_zip1', 'mb_zip2', 'mb_addr1', 'mb_addr2'),
'member',
'fregisterform',
"\t\t// g4s의 경우 old_email 과 mb_nick_default가 더 있음.
\t\tif (i == 'mb_email' && f.elements['old_email']) f.elements['old_email'].value = aes.decrypt(encrypt_data[i], aes_key);
\t\telse if (i == 'mb_nick' && f.elements['mb_nick_default']) f.elements['mb_nick_default'].value = aes.decrypt(encrypt_data[i], aes_key);"
);
?>

[/code]

다음의 코드를 찾는다.
[code]
<? echo chk_captcha_js(); ?>

return true;
[/code]

이 코드를 다음으로 "교체"한다.
[code]
<? echo chk_captcha_js(); ?>

<?php http_openssl_js_form_submit('f'); ?>

[/code]

6. skin/member/basic/register_form_update.tail.skin.php를 연다.
---------------------------------------------------------------

다음의 코드를 찾는다.
[code]
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
[/code]

찾은 코드 "뒤"에 다음의 코드를 "추가"한다.
[code]

http_openssl_save_session();

[/code]

7. skin/outlogin/basic/outlogin.skin.1.php 를 연다.
---------------------------------------------------

다음의 코드를 찾는다.
[code]
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
[/code]

찾은 코드 "뒤"에 다음의 코드를 "추가"한다.
[code]

http_openssl_simple_prepare();

[/code]

다음의 코드를 찾는다.
[code]
function fhead_submit(f)
{
return true;
}
[/code]

이 코드를 다음으로 "교체"한다.
[code]
function fhead_submit(f)
{

<?php http_openssl_js_form_submit('f'); ?>

}
[/code]

8. adm/admin.menu100.php를 연다.
--------------------------------

다음의 코드를 찾는다.
[code]
array('', '관리권한설정', G4_ADMIN_URL.'/auth_list.php', 'cf_auth'),
[/code]

찾은 코드 "뒤"에 다음의 코드를 "추가"한다.
[code]
array('', 'OpenSSL for HTTP설정', G4_ADMIN_URL.'/http_openssl_form.php', 'cf_http_openssl'),
[/code]

첨부된 압축파일을 푼 폴더에 보면 adm이란 폴더 안에 있는 두 개의 파일(http_openssl_form.php 와 http_openssl_form_update.php)를
adm 폴더로 "이동"한다.


9. adm/member_list.php를 연다.
------------------------------

다음의 코드를 찾는다.
[code]
<form id="fsearch" name="fsearch" method="get">
[/code]

찾은 코드 "앞"에 다음의 코드를 "추가"한다.
[code]
<?php
http_openssl_simple_prepare(true,
"var encrypted_aes_key = rsa.encrypt(BASE64.encode(aes_key));

// GET방식으로 encrypted_aes_key를 전송한다.
$(document).ready(function(){
$('a[href*=\"/member_form.php\"]').each(function () {
var href = $(this).attr('href');
if(href.match(/(\&|\?)w=u/gi) && !href.match(/(\&|\?)encrypted_aes_key=/gi)) $(this).attr('href', href+'&encrypted_aes_key='+encrypted_aes_key);
});
});");
?>
[/code]


10. adm/member_form.php를 연다.
------------------------------

다음의 코드를 찾는다.
[code]
<form name="fmember" id="fmember" action="./member_form_update.php" onsubmit="return fmember_submit(this);" method="post" enctype="multipart/form-data">
[/code]

찾은 코드 "앞"에 다음의 코드를 "추가"한다.
[code]

<?php

http_openssl_prepare(
'w', 'u',
array('mb_id', 'mb_nick', 'mb_name', 'mb_email', 'mb_birth', 'mb_homepage', 'mb_tel', 'mb_hp', 'mb_zip1', 'mb_zip2', 'mb_addr1', 'mb_addr2', 'mb_memo', 'mb_profile'),
'mb',
'fmember',
""
);
?>

[/code]

다음의 코드를 찾는다.
[code]
function fmember_submit(f)
{
if (!f.mb_icon.value.match(/\.(gif|jp['e']g|png)$/i) && f.mb_icon.value) {
alert('아이콘이 이미지 파일이 아닙니다. (bmp 제외)');
return false;
}

return true;
}
[/code]

찾은 코드를 다음으로 "교체"한다.

[code]
function fmember_submit(f)
{
if (!f.mb_icon.value.match(/\.(gif|jp['e']g|png)$/i) && f.mb_icon.value) {
alert('아이콘이 이미지 파일이 아닙니다. (bmp 제외)');
return false;
}

<?php http_openssl_js_form_submit('f'); ?>

}


[/code]


11. adm/member_form_update.php를 연다.
--------------------------------------

다음의 코드를 찾는다.
[code]
goto_url('./member_form.php?'.$qstr.'&amp;w=u&amp;mb_id='.$mb_id, false);
[/code]

찾은 코드 "앞"에 다음을 "추가"한다.
[code]

http_openssl_save_session();

[/code]



12. adm/admin.head.php 를 연다.

다음의 코드를 찾는다.
[code]
<header id="hd">
[/code]

찾은 코드 "앞"에 다음을 "추가"한다.
[code]
<?php
http_openssl_simple_prepare(true,
"var encrypted_aes_key = rsa.encrypt(BASE64.encode(aes_key));

// GET방식으로 encrypted_aes_key를 전송한다.
$(document).ready(function(){
$('a[href*=\"/member_form.php\"]').each(function () {
var href = $(this).attr('href');
if(href.match(/(\&|\?)w=u/gi)) $(this).attr('href', href+'&encrypted_aes_key='+encrypted_aes_key);
});
});");
?>
[/code]


13. http_openssl을 사용하기 위해서는 RSA 키를 생성해야 한다.
------------------------------------------------------------

따라서 완료가 되면 adm/http_openssl_form.php로 이동하여 세팅을 해야 한다.

관리자 로그인 후 관리자 페이지에서 "환경설정->OpenSSL for HTTP설정"으로 가서
OpenSSL for HTTP 사용에 체크하고 아래 RSA 키 생성에 체크를 한 후 관리자 비번 넣고 "확인"을 누르면
잠시 화면이 멈추어 있을 겁니다. 다운된 것이 아니라 RSA 키생성 시간이 오래 걸리니 기다리고 있으면 됩니다. 만일 서버에서 bcmath를 사용하지 않는다면 대략 난감...

그럴 때는 압축푼 파일 안에 rsa_keygen.html이란 파일이 있습니다. 이걸 실행하고 약간 기다리면
PEM public키와 private키가 나옵니다. 이 키값을 config 테이블에 넣어야 합니다.
cf_http_openssl_use 필드가 없으면 생성해서 값은 '1'을 주고
cf_pem_privatekey에 생성된 private 키값을, cf_pem_publickey 필드에는 public 값을 주면 됩니다.

대부분의 서버는 bcmath를 지원하기 때문에 브라우져가 다운되는 경우는 그렇게 많지 않을 겁니다.



많은 분들이 OpenSSL for HTTP를 적용하고도 SSL보안서버 구축을 한 가운데서 사용을 해야 하는지에 대해 궁금해 하는 것같습니다. OpenSSL for HTTP를 설치하였다면 SSL 보안서버 구축을 하지 않아도 됩니다. 다음은 관련 규정입니다. 규정에서 "보안서버는 다음 각 호 중 하나의 기능을 갖추어야 한다"가 있습니다. OpenSSL for HTTP는 이 중 두 번째에 해당합니다.

[code]
개인정보의 기술적/관리적 보호조치 기준
(방송통신위원회고시 제2009-21호)

제2조(정의) 이 기준에서 사용하는 용어의 뜻은 다음과 같다.
9. “보안서버”라 함은 정보통신망에서 송?수신하는 정보를 암호화하여 전송하는 웹 서버를 말한다.

제6조(개인정보의 암호화)
③ 정보통신서비스 제공자 등은 정보통신망을 통해 이용자의 개인정보 및 인증정보를 송/수신할 때에는 안전한 보안서버 구축 등의 조치를 통해 이를 암호화해야 한다. 보안서버는 다음 각 호 중 하나의 기능을 갖추어야 한다.
1. 웹 서버에 SSL(Secure Socket Layer) 인증서를 설치하여 전송하는 정보를 암호화하여 송/수신하는 기능
2. 웹 서버에 암호화 응용프로그램을 설치하여 전송하는 정보를 암호화하여 송/수신하는 기능
[/code]

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 41개

초보라 무슨말인지 잘을 이해는 어려우나, 보안을 위한 필수 작업같네요 감사합니다.,