포럼
쌩초보의 md5와 sha에 대한 짧은 생각
2013.11.07 00:50
안녕하세요.
프로그래밍에 대해서 전혀 모르는,
그러나 웹사이트를 직접 만들어보고 싶어서 초보용 PHP 책을 보기 시작한지 1 주일 정도 되는,
쌩초보입니다. ^^;;
xe를 사용하지 않고 순수 날코딩으로 웹사이트를 만들고 싶어서
책보고 하나하나 따라하고 있어요.
어제 오늘 2 일 동안 회원가입, 로그인, 로그아웃 기능을 구현하다가
xe로 운영하던 사이트의 회원 DB 를 새로운 테이블로 옮기고,
로그인 기능을 구현하다가 비밀번호 체크하는 곳에서,
책에 있는대로 따라했는데, 자꾸 에러가 나길래,
웹서핑을 몇 시간 동안 하다가,
책에는 sha 로 되어 있어서 그렇게 코딩했는데,
xe는 md5로 되어 있어서 에러났던걸로 확인했구요.
sha와 md5 에 대해 이곳에서 오고간 토론글들도 봤어요.
전 앞으로 sha로 할 건데,
이미 제 사이트에 가입되어 있는 1 만명 정도의 회원들의 md5 정보들을 어찌할까 고민하다가
아래와 같이 코딩했습니다.
=========================================================================================
$sql1="select * from 회원정보 테이블 where mem_id='$mem_id' and mem_pwd=sha('$mem_pwd')";
$sql2="select * from 회원정보 테이블 where mem_id='$mem_id' and mem_pwd=md5('$mem_pwd')";
$result1=mysql_query($sql1,$connect);
$result2=mysql_query($sql2,$connect);
$num_rows1=mysql_num_rows($result1);
$num_rows2=mysql_num_rows($result2);
if(!$num_rows1&&!$num_rows2) {
echo("
<script>
window.alert('로그인 정보가 정확하지 않습니다.');
history.go(-1);
</script>
");
} else {
if($num_rows1) { $row=mysql_fetch_array($result1); }
else { $row=mysql_fetch_array($result2); }
$_SESSION['s_srl']=$row[mem_srl];
$_SESSION['s_id']=$row[mem_id];
$_SESSION['s_nick']=$row[mem_nick];
echo("
<script>
history.go(-2);
</script>
");
=============================================================================================
전 초보용 책 본지 1 주일 밖에 안된 생초보라서 앞의 분들의 복잡한 이야기는 잘 모르겠지만,
xe core 에서 md5에서 sha 로 전환하는데 어려운 큰 이유가 기존 회원의 md5 정보를 sha 정보로 전환하기 힘든 점
이라는 것 같은데,
위와 같이 코딩을 하면 굳이 기존의 md5 를 sha 정보로 변경안해도 되고,
또 중요한 이슈 중에 하나가 xe 가 어차피 오픈소스이기 때문에 어떤 방식으로 암호화를 하는지가 다 노출되어 있어서
md5로 하나 sha로 하나 의미없다는 것 같던데요. (사실 이게 가장 큰 핵심인 것 같던데)
위 if 문에 md5, sha, 기타 등등(몇 가지 더 있는 것 같던데)을 현존하는 암호화 방식을 다 추가하고,
회원가입이나 회원정보수정 시에 사이트 관리자가 직접 고른 방식으로 암호화하게 하면,
아무리 오픈소스일지라도 어떤 암호화 방법을 쓰고 있는지 그대로 노출되지는 않을 것 같습니다.
"xe core 가 A 방식을 썼으니 A 로 무한 루프 돌리면 되겠군"
이러하기 때문에 어떤 방식을 써도 결국 똑같다는 논지는 초보인 제가 보기엔 좀 이상합니다.
어떤 방식을 쓸것인지 사이트 관리자가 직접 선택하게 만들면,
결국 어떤 방식을 사용했는지 모르게 될테니까요.
로그인할 때, 모든 방식으로 비교해서 하나라도 맞으면 로그인 성공인 것으로 코딩해버리고,
사이트 운영자가 고르는 방식으로 암호화하게끔만 하면,
해커 입장에서 모든 방식으로 다 시도를 해봐야 되니,
"오픈소스이기 때문에 암호화 방식이 무엇인지 노출되는 일" 은 해결되는 것 아닐까요?
xe core에서 비밀번호 입력받는 부분에 if 문 해결하는걸로 깔끔히 해결될 것 같아서요.
xe core 개발자가 "어떤 방식을 쓸 것이냐" 고민하지 않고,
어떤 방식을 쓰더라도 (게다가 수시로 이리저리 방식을 변경하더라도)
로그인 기능이 제대로 수행되게끔만 만들어두어서
"어떤 방식을 쓸 것이냐" 를 xe 유저가 직접 고르게끔 하면 말끔히 해결될 것 같습니다.
게다가 사이트 관리자가 수시로 방식을 바꿔가면서 2~3 가지를 돌아가면서 사용하면,
그 사이트는 여러 가지 방법이 모두 섞여 있으니, 무한루프를 좀 더 고생스럽게 한다는 효과도 있을 수도 있겠구요.
오늘 하루종일 로그인 에러 때문에 끙끙거리다가 드디어 해결해서 기분좋게 잠자러 가던 중에 짧은 생각 남겨봅니다.
제 말이 너무 말도 안되는 초보스러운 글이라도 양해바랍니다.
진짜 쌩초보거든요. ^^;;
그럼, 굿나잇!! ^^
댓글 14
-
도라미
2013.11.07 01:20
-
비밀임다
2013.11.07 01:32
아! 그런가요?
mysql 은 길이 수정 수시로 되던데, 다른건 몰라서요. ^^;;
그런데, 정말 생초보라서 궁금한데요.
varchar 길이를 애초부터 255 주고 시작하면 안되나요? (최대가 255 맞나요?)
-
비밀임다
2013.11.07 01:45
아!!
그리고, 암호화 방법을 사이트 관리자가 수시로 바꾸는건 잠깐 삼천포였구요.
코딩을 저렇게 if문으로 해놓고,
xe 설치할 때, 암호화 방법을 어떻게 할거냐를 선택하면
그것에 맞게 varchar 크기를 정하면 되지 않나요?
그리고, 방법을 변경할 때도 관리자모드에서 암호화 방법 변경을 선택하면,
새로운 방법에 맞춰 회원테이블 혹은 비밀번호 테이블을 새로운 varchar에 맞춰 테이블을 생성해서, 새로운 테이블로 DB를 복사하고, 새로운 테이블에서 비밀번호를 참조하게끔 하면 되지 않을까요?
물론 본문에 있는 sql의 테이블 명을 상수가 아니라 변수처리해두면서 말이죠.
"사이트 관리자가 어떤 방식을 선택하든 다 지원하게끔 만든다" 에 초점을 맞추면 구현될 것 같아요.
-
도라미
2013.11.07 01:55
예전 md5 관련 글 이후로 xe 코어에 보면 sha1 옵션이 추가되어 있긴합니다.
그리고 너무 많은 경우의수 (옵션)이 늘어나면 느려질수밖에 없습니다..
-
비밀임다
2013.11.07 11:38
아, 그렇군요. XE에 sha 옵션 추가 되어 있군요.
뒷북글이었네요. ㅎ
-
푸시아
2013.11.07 03:08
일단.... xe 에서 패스워드는
if($args->password)
{
if($this->useSha1 && function_exists('sha1'))
{
$args->password = md5(sha1(md5($args->password)));
}
else
{
$args->password = md5($args->password);
}
}
else if($args->hashed_password)
{
$args->password = $args->hashed_password;
}이렇게 처리되는 것 같습니다.
-
비밀임다
2013.11.07 11:38
아!! 이미 if문 적용했군요. if문으로 둘 다 가져갈 수 있는 심플한 문제인데,
md5 냐 sha 냐 가지고 토론이 길게 이어지던 이전 글들 보고 글 남겼는데,
너무 오래전 일이었나보네요. ㅎ
-
criuce
2013.11.07 14:35
또 중요한 이슈 중에 하나가 xe 가 어차피 오픈소스이기 때문에 어떤 방식으로 암호화를 하는지가 다 노출되어 있어서
md5로 하나 sha로 하나 의미없다는 것 같던데요. (사실 이게 가장 큰 핵심인 것 같던데)
--
이렇게 말씀하셨는데 잘못 이해하고 계세요. 어떤 방식(어떤 알고리즘을 쓰느냐가 아닌)으로 암호화를 하느냐가 보안에 있어 가장 중요합니다.
현재 인터넷 상에 해쉬사전이라 해서 a->(sha, md5)->b 이런방식이 사전 형식으로 돌아다니고 있습니다. 그래서 해시키 만으로도 쉽게 원문을 유추할 수 있고요. 그래서 sha든 md5든 보안에 있어 둘다 형편없다고 보여지고요. 좀 더 좋은 방식은 여러번 반복해서 해시하는 겁니다.
$a = 'abcd';
for($i=0;$i<10;$i++) {
$a = md5($a);
}
이런식으로 말이죠.
더 좋은 방식은 솔팅이라고 해서 임의의 문자를 대입하는 것입니다.
$a = 'abcd';
$b = $a;
for($i=0;$i<10;$i++) {
$a = md5($a.$b);
}
이런식으로 말이죠.
하지만 해시라는게 단순히 보안 뿐만 아니라 성능을 비롯한 다양한 변수들을 고려해야 하므로 그냥 있는거 쓰는게 제일 좋습니다.
password_hash 함수(php 5.5에 추가) 쓰세요.
-
비밀임다
2013.11.07 16:33
오! 제가 잘못 이해했군요.
깔끔히 정리해주셔서 감사합니다.
게다가 여러번 반복 또는 솔팅이라는 방법과 코드도 감사합니다.
바로 적용해봐야겠네요. 감사합니다. ^^
-
비밀임다
2013.11.08 20:34
확인해보니 제가 사용하는 웹호스팅은 아직 php5.5 가 아니네요. ^^;;
sha512 로
위에 적어주신 소스를 응용하여 솔팅과 반복해시까지 적용해서
코딩을 완료했습니다.
sha는 40글자인데, sha512는 128글자네요.
이렇게 하면 md5나 sha보다 훨씬 강력한것 맞죠?
정말 감사합니다. ^^
-
criuce
2013.11.08 20:42
네 글자가 길수록 더 좋죠.
다만 db에 password 컬럼의 속성 길이를 꼭 128글자 이상으로 해주셔야 합니다~
-
비밀임다
2013.11.15 04:41
넵! 감사합니다. ^^
-
sol
2013.11.07 20:37
이런글은 개발자 포럼이 좋을 것 같습니다.
-
chansol
2013.11.10 00:27
어떻게 암호화를 한다고 코드에서 보여지더라도, 암호화는 하는게 맞습니다.
오픈소스라고 암호화를 안해버리면 ... 누가 그 프로그램을 사용할까요...
XE는 여러 DB를 지원하다보니 한번정한 암호화 방식을 바꾸기가 어려운 상황입니다.varchar 길이가 수정안되는 DB에선 곤란해지기 때문이죠...정정합니다. 정확하게 머였는지 기억이 안나네요. 예전에 sha1로 바꾸는 코드 때문에 안된다 소리를 듣긴들었는데 기억이 나지않네요. 불확실하니 일단 지우겠습니다.