모다의 윈도우폰7 뚝딱 팩토리(11)-보안 프로그래밍
한국마이크로소프트에서 초급 스마트폰 개발자 분들을 위해 공개하는 모다의 윈도우폰7 뚝딱 팩토리 열한번째 영상!
유무선을 막론하고, 중요한 것이 바로 보안입니다. 정말 간단한 어플리케이션이 아닌 이상, 항상 보안과 관련된 문제에 부딪히기 마련인데요, 특히 스마트폰 위에 올라가는 어플리케이션들은 민감한 개인정보를 활용 할 수 있고, 노출이 잘 되는 무선 환경을 사용하기 때문에 더더욱 조심하셔야 합니다.
Launcher and Chooser / 격리된 저장소처럼 윈도우 폰의 기본 기능/환경으로 제공하는 보안기능도 있지만 개발자가 직접 프로그래밍을 해 주셔야 하는 부분도 존재합니다. 예를 들어 통신과 관련된 어플리케이션을 만들었는데, 내가 무엇을 검색하고 누구한테 어떤 메세지를 보내는지 모두 노출이 되면 사용자 입장에서는 달갑지 않은 느낌이 들겠죠. 이러한 문제들을 덜기 위해서 도입하는 방법이 바로 암호화입니다. 그리고 윈도우폰에서는 이러한 암호화 프로그래밍을 조금 더 생산적으로 하기 위해 6가지 보안 알고리즘을 기본적으로 지원합니다. 물론 외부 라이브러리나 직접 코딩하는 방법등을 통해서 다른 알고리즘을 구현 할 수도 있습니다.
동영상의 예제에서는 단방향 암호화 알고리즘인 SHA를 이용해서 비밀번호를 안전하게 체크하는 방법을 사용하고 있는데요, 이해를 돕기 위해 비밀번호가 무엇인지 string 값에 비밀번화를 직접 대입하고 시연을 하였지만, 실제 프로그래밍에서 영상처럼 암호화되지 않은 비밀번호(전문용어로는 plaintext라고 합니다)를 하드코딩하는 방법은 위험한 방법입니다. 사용자가 직접 볼 수는 없지만, 리버스 엔지니어링 등 각종 해킹 시도로 노출이 될 가능성이 더 높아지기 때문이지요. 따라서 예제 동영상보다 조금 더 안전한 프로그래밍을 하시려면 한번 암호화를 거친 ByteArray 자체를 직접 하드코딩 하시는 방법이 더욱 안전합니다.
보안 자체는 상당히 복잡한 학문입니다. 수학과 컴퓨터과학이 결합되어 있고, 그 자체를 모두 이해하려면 오랜 시간이 소요되므로 많은 학교나 학원 등의 교육기관에서 별도의 교육과정을 두고 있는 것을 보실 수가 있습니다. 따라서, 보안 알고리즘이 어떻게 되어있고, 어떤 상황에 사용해야 하는지에 대한 자세한 사항은 전문 문서나 서적 등을 참고해 주세요.
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Net;
5: using System.Windows;
6: using System.Windows.Controls;
7: using System.Windows.Documents;
8: using System.Windows.Input;
9: using System.Windows.Media;
10: using System.Windows.Media.Animation;
11: using System.Windows.Shapes;
12: using Microsoft.Phone.Controls;
13:
14: using System.Security.Cryptography;
15: using System.Text;
16:
17: namespace securityWP7
18: {
19: public partial class MainPage : PhoneApplicationPage
20: {
21: // 암호화 되지 않은 비밀번호를 하드코딩하는 방법은 가급적 피해주시기 바랍니다
22: private string originalPassword = "MODA";
23: private UnicodeEncoding uniEncoder;
24: private byte[] originalPasswordByteCode;
25:
26: // Constructor
27: public MainPage()
28: {
29: InitializeComponent();
30:
31: // 바이트코드로 변환
32: uniEncoder = new UnicodeEncoding();
33: originalPasswordByteCode = uniEncoder.GetBytes(originalPassword);
34: }
35:
36: private void button1_Click(object sender, RoutedEventArgs e)
37: {
38: if (checkPassword(textBox1.Text))
39: {
40: MessageBox.Show("Password Confirmed");
41: }
42: else
43: {
44: MessageBox.Show("Incorrect Password");
45: }
46: }
47:
48: private bool checkPassword(string inputPassword)
49: {
50: // throw new NotImplementedException();
51: SHA1Managed hasher = new SHA1Managed();
52: int i;
53:
54: // 사용자 입력을 바이트코드로 변환
55: byte[] userInputbyByteCode = uniEncoder.GetBytes(inputPassword);
56: // 변환된 바이트코드를 SHA1 해싱
57: byte[] hashedUserInput = hasher.ComputeHash(userInputbyByteCode);
58: // 저장된 패스워드도 해싱
59: byte[] hashedPassword = hasher.ComputeHash(originalPasswordByteCode);
60:
61: // 두 byte[] 배열이 동일한지 확인
62: for (i = 0; i < hashedPassword.Length; i++)
63: {
64: if (hashedPassword[i] != hashedUserInput[i])
65: return false;
66: }
67: return true;
68: }
69: }
70: }