Visual Basic, C & C++
분류 Visual Basic

MYSQL의 password함수를 vb .net에서 구현하기 (그누보드4 vb .net 로그인)

페이지 정보

본문

[펌] http://b0ks1n.tistory.com/245

단순 정보를 위해 오신 분은 본문의 끝부분을 봐주세요. 시간이 넘쳐흐르시는분은 정독하셔도 좋습니다. 얻어갈건 없으니까요!



개인적으로 만들고있는 프로그램이 로그인을 지원할 필요가 있었다.

처음에는 프로그램 자체에다 db에 접속하는 뭐 그런걸 어떻게 연동해보려는 생각을 해서 검색을 해봤으나 복잡해서 그냥 때려치고(MYSQL Connector라는녀석을 설치하면 vb에서 바로 연결이 되는 것 같다)
프로그램에서 서버의 php같은 파일로 패킷을 쏘면 php가 받은 패킷을 적절히 처리하여 로그인 결과를 다시 프로그램으로 보내주는 방식으로 하기로 했다.

로그인으로 연동될 회원시스템은 그누보드4 시스템인데, 그누보드4는 비밀번호를 저장할때 password함수를 이용한다.
password함수는 복호화가 불가능한 해시 알고리즘을 이용한 암호화함수중 하나이다.

처음에는 아래와 같은 방식으로 로그인시스템 코딩을 했었다.
아 참고로 이 코드는 매우 비효율적인 코드라고 생각하지만 아직도 씀.

코드 가독성이 매우 떨어진다. 양해를 구한다. 색상구분해서 강조하기 솔직히 귀찮음 ㅈㅅㅈㅅ

vb .net
webClient 객체를 생성하고, 이 객체의 DownloadString함수를 이용한다.

Dim tmpWC as New System.Net.WebClient
Dim tmpString as String
tmpString = tmpWC.DownloadString("http://홈페이지/login.php?id=" & txtID.text & "&pw=" & txtPW.text)

tmpString에는 로그인 요청 결과값이 들어있다.

login.php
GET형식으로 값을 받은다음에, echo함수를 통해 로그인 성공시 1, 실패시 0을 출력한다.
코드는 알아서 상상하셈 대충올림

 <?
$id = $_GET["id"];
$pw = $_GET["pw"];

//이것저것 db접속관련 변수와 함수 만들고

$pw2 = ~~~; //mySQL에 password함수를 이용하는 쿼리를 요청한다. $pw를 암호화해서 $pw2에 처박는다.

//g4_member테이블에서 mb_id필드중 $id와 일치하는 항목이 있는지 찾아보고 있으면
//mb_password의 값과 $pw2의 값과 비교함

if (맞으면)
  echo("1");
else
 echo("0");

?>

뭐 대충 이런구조로.


맨처음엔 이런식으로 로그인(이라기보단 접속해서 db의 정보를 받아오는) 시스템을 만들었었다.

근데 이렇게 할 경우 패킷에 비밀번호가 그대로 노출이 된다. 즉, 패킷이 따이고있다면 비번도 털리게된다.
vb에서 서버php로 패킷을 보낼 때 아이디와 비밀번호를 그대로 보내고, 비밀번호 대조를 위해 하는 암호화는 서버에서 이루어지기 때문이다.

그래서 당연히 나는 비밀번호를 프로그램에서 미리 암호화해서 서버로 보낼 필요가 있다고 생각했다.
이 생각을 맨 처음 했을때는 내가 개념이 없었으므로 그냥 단순히 이 생각을 했다.
-> base64같은 간단한 암호화알고리즘을 이용해 vb에서 암호화하고, php에서 복호화한다음에 password함수 이용해서 처리

근데 이렇게하면 패킷을 간단히 복호화해버리면 암호가 노출이되므로 당연히 이건 생각하자마자 접었다.


그리고 떠오른게
php에서 처리할 password함수를 미리 vb에서 처리한 후에 패킷을 보내면 된다는 생각이었다.
졸라무식함 이게 이제야 떠오르다니

이런식으로 처리하면 패킷이 따이더라도 비밀번호는 암호화된 상태이므로 노출이 안되고, php는 그냥 받은 값을 그대로 db값과 대조하기만 하면 되기때문에 php코드도 더 간단해지고 하여튼 여러모로 좋을것이다.

그래서 찾아봄
"VB .NET password함수"
"비주얼베이직 닷넷 mySQL password"
"비베 mySQL 암호화"
.
.
.
내가 눈알이 호구인지 어쨌는진몰라도 네이버에서는 방법을 찾을 수 없었다.

결국 구글에
"vb .net mysql password function"

으로 검색하니까 대충 방법이 나오더라.

.NET에는 각종 암호화 클래스가 존재하는데, 단지 이녀석을 이용하기만 하면 시중의 모든 암호화를 구현할 수 있다는 내용이었다.
기분이 개좋아져서 글에 쓰여있는대로 코딩하고 실행해봤다.

치기 귀찮아서 실제코드로부터 복사해온다.

Dim Enc As New System.Security.Cryptography.SHA1Managed
Dim tmpPWByte() As Byte, tmpText2Byte() As Byte, passwd As String, sbuilder As New System.Text.StringBuilder

tmpText2Byte = System.Text.Encoding.Default.GetBytes(txtPW.Text)
tmpPWByte = Enc.ComputeHash(tmpText2Byte)

For i As Short = 0 To tmpPWByte.Length - 1
         sbuilder.Append(tmpPWByte(i).ToString("X2"))
Next
passwd = "*" & sbuilder.ToString

Byte타입에 대해 제대로 아는게 없지만, 대충 살펴보면

txtPW.text에는 입력된 비밀번호가 담겨있다.
이녀석을 Byte(배열)타입으로 변경해준다. (암호화클래스의 ComputeHash는  Byte타입의 내용물만 계산이 가능하나봄)
그리고 ComputeHash함수를 이용하여 암호화를 해준다.
아, 참고로 mySQL의 password함수는 SHA1 해시 알고리즘을 통해 작동되는 것 같다.
뭐 암호화됐으면 이제 그 암호화된 Byte값들을 다시 String(대문자)으로 바꿔주고, 맨 앞에 *을 붙이면 password함수가 된댄다.
passwd라는 변수 안에 암호화된 문자열이 들어있다는것인데..

+ db에 비번이 저장되는 꼴을 봤다면, 맨 앞에 *이 달려있다. 왜달려있는지는 모르겠고 그냥 *을 붙여준다.


구글에 나온대로 위와 같이 코딩하고 실행해봤는데 글쎄 비번이 틀렸댄다.
디버깅해보니까 암호화된 결과가 다르더라, 제길!


구글은 내용이 방대한만큼 거짓자료도 많은 것 같다고 생각한 순간 호기심이 돌았다.
위 코드는 암호화를 한번했는데, 한번 더 해봐야겠다는 쓸때없는 생각이었다.

코드를 아래와 같이 바꿔보았다.

Dim Enc As New System.Security.Cryptography.SHA1Managed
Dim tmpPWByte() As Byte, tmpText2Byte() As Byte, passwd As String, sbuilder As New System.Text.StringBuilder

tmpText2Byte = System.Text.Encoding.Default.GetBytes(txtPW.Text)
tmpPWByte = Enc.ComputeHash(Enc.ComputeHash(tmpText2Byte))

For i As Short = 0 To tmpPWByte.Length - 1
         sbuilder.Append(tmpPWByte(i).ToString("X2"))
Next
passwd = "*" & sbuilder.ToString

5번째(?)줄에 tmpPWByte변수에 값을 넣는 줄에서 Enc.ComputeHash를 연속 두번 사용해준거 이거 하나 변했다.


그리고 로그인을 시도하니


되더라.

ㅇ 로그인 잘 되더라. 

"그리고 기분이 좋아졌습니다."

하여튼 vb .NET으로 password함수를 구현해낼 수 있다.



결론

VB .NET에서 MYSQL의 password함수를 구현하기 (그누보드4의 db에 저장된 비밀번호 값처럼 암호화하기)
*sbuilder As New System.Text.StringBuilder 한줄입니다. 엔터ㄴㄴ

Dim Enc As New System.Security.Cryptography.SHA1Managed
Dim tmpPWByte() As Byte, tmpText2Byte() As Byte, passwd As String, sbuilder As New System.Text.StringBuilder

tmpText2Byte = System.Text.Encoding.Default.GetBytes(txtPW.Text)
tmpPWByte = Enc.ComputeHash(Enc.ComputeHash(tmpText2Byte))

For i As Short = 0 To tmpPWByte.Length - 1
         sbuilder.Append(tmpPWByte(i).ToString("X2"))
Next
passwd = "*" & sbuilder.ToString

이 코드를 이용하시면 됩니다.
txtPW가 비밀번호가 입력될 텍스트박스이고, passwd변수가 암호화된 비밀번호 문자열이 저장된 변수입니다.
패킷을 보낼 때 passwd의 값을 보내면 됩니다.
필요한경우 txtPW.text와 Trim함수를 같이 사용하면 더 좋을지도 모르겠네요.



뭐 하여튼 이런식으로 하면 어느정도 그누보드4의 회원시스템을 vb .net에서도 가져와 사용할 수는 있습니다.

얼마전에 만든 프로그램중에 스트리밍음악재생기가 있었는데(4쉐어드 이용) 목록을 홈피서버의 db에 저장함으로써 어느 컴퓨터에서든 자신이 만든 목록의 음악을 들을 수 있는 쩌는녀석이었습니다.
프로그램에서 로그인만 하면 자신의 목록을 불러올 수 있으니까요. 이 때 사용한 비밀번호 암호화방법이 위의 코드와 같습니다.

이 프로그램 어떻게보면 대단한녀석이긴 한데, 여러모로 지적재산권(음반 저작권)관련 문제가 걸릴꺼같아 결국 미루었습니다.

아니 사용자가 직접 찾아듣는 스트리밍플레이어인데도 이런걸 신경써야하다니 세상 참 잔인하다고 생각합니다.
(근데 솔직히 음악가 입장에서도 자기노래 그냥 공짜로 들으면 뭔가 억울할꺼같음)
이게 걸리게될경우 스트리밍으로 음악을 들려주는 음악블로그들은 다 감방가야될텐데

하여튼 password함수는 저딴식으로 만들면 되겠습니다.

관련자료

등록된 댓글이 없습니다.
프로그래밍
Today's proverb
생각은 우물을 파는 것과 닮았다. 처음에는 흐려져 있지만 차차 맑아진다.