보안과암호화기법 (Security and Cryptograph Techniques) 대부분의클라이언트 / 서버어플리케이션에서는 ID 와패스워드를묻는최소한의보안을하고있다. 그렇지만, 데이터암호화등의다소높은수준의보안이요구되는경우도많다. 이러한주제를가지고정말로많은양의문서와책들이쓰여져왔고, 그리고많은연구도진행중이다. 그렇지만, 여기에서다루고자하는것은그렇게이론적이고어려운암호화기법에대한것이아니다. 실제로델파이어플리케이션을사용하면서간단하게이용할수있는암호화기법에대해서알아보고, 이를실제로구현하여적용하는방법에대해서알아볼것이다. 그리고, 현재실용화되어사용되고있는표준암호화알고리즘의종류와이들을지원하는컴포넌트를소개하고이를사용하는방법에대해서알아보도록한다. 패스워드와 XOR 암호화 보통의경우어플리케이션에패스워드를이용해서보안을하는경우가많다. 그런데, 이렇게사용하는패스워드를.INI 파일이나레지스트리, 일반텍스트파일등에기록할경우아무나쉽게패스워드를간파할수있게된다. 이럴때에기본적인암호화기법이필요한데, 가장쉬우면서도유용하게쓸수있는것이 XOR 암호화기법이다. 이암호화기법은개념적으로도매우쉽고, 알고리즘이간단하기때문에수행속도도매우빠른것이장점이다. 단점은키를알게되면쉽게깨질수있다는것이다. XOR 암호화기법을적용하기위해서는키가되는숫자를이용하게된다. 이를키번호 ( 키 number) 라고하며이를이용해서메시지를암호화하거나, 해독한다. 사용방법은암호화하고자하는문자나숫자를키번호와 XOR 연산을행해서나오는값을저장하고, 이를해독할때에는역시키번호로 XOR 연산을하면된다. 그러면, 실제로이를구현하는코드를살펴보자. procedure XORBuffer(Buffer: TMemoryStream; 키 : String); var Len, Place: Word; Character: Char; Size: Integer; Buffer.Seek(0, 0);
Len := Length( 키 ); Place := 1; Size := Buffer.Size; while Size > 0 do Buffer.Read(Character, 1); Character := Char(Byte(Character) xor Byte( 키 [Place])); Buffer.Seek(-1, 1); Buffer.Write(Character, 1); Inc(Place); if Place > Len then Place := 1; Dec(Size); 키번호를문자열로받아서그길이를이용해서반복하도록하고, 암호화가될문자열은버퍼에담아서이를키번호와 xor 연산을함으로써암호화하는것이다. 여기에서는 TMemoryStream 클래스를사용했는데, 문자열을사용하지않은이유는 xor 연산의결과가 0 일경우 PChar 문자열의마지막문자임을나타내게되므로, 이러한문자열의규칙에위배되지않기위해서스트림을이용하였다. 그렇지만, 이렇게암호화한내용을.INI 파일이나레지스트리에저장하고자하면문자열로의변환과정이필요하다. UUEncoding 과 UUDecoding 유닉스는 8 비트의데이터중 7 비트를사용하는통신시스템을가진경우가많은데, 이를해결하기위한방법으로알려진것이 UUEncoding, UUDecoding 이라는것이다. 이방법을사용하면데이터를! 문자인 ASCII 33 부터 z 인 ASCII 122 까지의문자로변환하는것으로, 이를이용하면 3 개의문자를 4 개의바이트에담게된다. 이후 4 개의바이트는마스크를거쳐서 32 를더해서결과값으로출력된다. 이방법의단점은암호화된데이터가원래의이진데이터보다 1/4 정도커진다는것이지만, 크게문제가되지는않는다 / UUEncoding 을이용한암호화프로시저의코드는다음과같다. procedure UUEncodeBuffer(InBuffer, OutBuffer: PChar; InSize: Word; OutSize: Word); var Chars: Array[0..3] of Byte; Hunk: Array[0..2] of Byte;
i: Integer; OutSize := 0; repeat FillChar(Chars, 4, 0); if InSize > 3 then Move(InBuffer^, Hunk, 3); Inc(InBuffer, 3); Dec(InSize, 3); end else Move(InBuffer^, Hunk, InSize); Inc(InBuffer, InSize); Dec(InSize, InSize); Chars[0] := Hunk[0] shr 2; Chars[1] := (Hunk[0] shl 4) + (Hunk[1] shr 4); Chars[2] := (Hunk[1] shl 2) + (Hunk[2] shr 6); Chars[3] := Hunk[2] and $3F; for i := 0 to 3 do Chars[i] := (Chars[i] and $3F) + 32; Move(Chars, OutBuffer^, 4); Inc(OutBuffer, 4); Inc(OutSize, 4); until InSize <= 0; 쉽게말하자면암호화할데이터를 InBuffer, 데이터의크기를 InSize 에담아오면암호화를거쳐서암호화된데이터를 OutBuffer, 크기를 OutSize 로반환하는프로시저이다. 이때 3 바이트를 4 바이트로 (3 바이트에 8 비트를 6 비트씩 4 바이트로 ) 저장한후, 이를 $3F 로마스크한후, 32 를더해서 OutBuffer 에결과값으로변환하는작업을한다. 이런 UUEncoding 알고리즘을이용한암호화데이터를풀때에는다음과같은 UUDecoding 프로시저를사용한다. procedure UUDecodeBuffer(InBuffer, OutBuffer: PChar; InSize: Word; OutSize: Word);
var Chars: Arrays[0..3] of Byte; Hunk: Arrays[0..2] of Byte; i: Integer; OutSize := 0; repeat FillChar(Hunk, 3, 0); if InSize >= 4 then Move(InBuffer^, Chars, 4); Inc(InBuffer, 4); Dec(InSize, 4); end else Move(InBuffer^, Chars, InSize); Inc(InBuffer, InSize); Dec(InSize, InSize); for i := 0 to 3 do if Chars[i] = Ord( ` ) then Chars[i] := Ord( ); Chars[i] := Chars[i] 32; Hunk[0] := (Chars[0] shl 2) + (Chars[1] shr 4); Hunk[1] := (Chars[1] shl 4) + (Chars[2] shr 2); Hunk[2] := (Chars[2] shl 6) + Chars[3]; Move(Hunk, OutBuffer^, 3); Inc(OutBuffer, 3); Inc(OutSize, 3); until InSize <= 0; 이런방식으로 UUEncoding, UUDecoding 을사용하면.INI 파일이나레지스트리에데이터 를저장할수있다. 앞에서설명한 xor 암호화기법을같이혼용해서일단데이터를 xor
로암호화한뒤이를 UUEncoding 알고리즘을이용해서변환한뒤이를저장하고, 해독할 때에는 UUDecoding 알고리즘을이용해서푼뒤, 이를다시 xor 을이용해서원래의값을 얻어내게된다. 암호화컴포넌트와표준알고리즘 암호화라는것은앞에서예를들어설명한것과같이특정알고리즘이나계산식등을통해데이터를변경하고, 변경된데이터를원할때다시원래의데이터로변환할수있는것을모두포함한것이다. 이러한암호화알고리즘에는크게나누어 private-키와 publick-키알고리즘으로구분할수있다. Private 키알고리즘을사용할때에는사용자가암호화와해독과정을모두같은키로할수있게된다. 데이터가같은위치에있을경우에는이것이문제가되지않지만, 데이터가전송되어야할경우에는문제가될수있다. 예를들어, 보안이요구되는메시지를전송한다고할때전송하는사람이 private 키를사용해서메시지를암호화한뒤에메시지를보냈다고하자, 그러면이를받는사람은암호화하는데사용한 private 키를이용해서메시지를해독해야한다. 그런데, 문제는이렇게해독할열쇠가되는 private 키를어떻게안전하게얻을수있는가하는문제이다. 이문제를해결하기위해 1976 년처음개발된방법이바로 public-키암호화기법이다. 이방법은데이터를암호화하고해독하는데 2 개의연관되었지만다른키를사용하는것이다. 이때암호화키를 public 키라고하는데, 이렇게암호화를하는데사용된키가해독하는데사용되지않기때문에키가발견될염려가없다. 이때데이터를해독할때에는 private 키가사용된다. 이제암호화된메시지를전송하고자하면, 전송하고자하는사람이 public 키를보내고이를이용해서메시지를암호화한다. 그리고, 암호화된메시지를받은쪽에서는자신의 private 키를사용해서해독하면된다. Private-키암호화는쉽게말해서데이터에대한패스워드를알고있는사람들끼리만이패스워드를이용한해슁함수를처리함으로써암호화를하는방법이고, public-키암호화는패스워드를걸지않고도일반적인데이터에대한 public-키를생성해서암호화를하는방법이다. Public-키암호화알고리즘은 private-키알고리즘에비해암호화와해독을할때 1,000 배가더걸린다. 또한, Public-키암호는 private-키암호에비해같은정도의보안레벨을제공하기위해서는 10 배는더길어야한다. 표준화된암호화알고리즘으로는매우여러가지가있지만널리쓰이는것으로는 DES, MD5, RC5, SHA 등이있다. 이들은모두 public-키암호화기법으로이들중에서 DES 와 SHA 에대해서알아보자. 그에비해앞에서설명한 XOR 연산자를이용한암호화는일종의 private-키암호화기법이라고말할수있다.
DES DES 는 Data Encryption Standard 의약자로암호학계에서 20 년간의테스트를거친알고리즘이기때문에특별한약점이없는표준적인알고리즘이다. DES 는암호화와해독을위해서 64 비트블록에대해서 56 비트의키를사용한다. 최근의경향으로보아 56 비트의키는다소짧다는의견이대두되고있지만, 보안의정도가아주높아야하는경우를제외하고는사용하는데큰무리가없다. SHA SHA 는 Secure Hash Algorithm 의약자로 NIST 와 NSA 에서개발된암호화표준이다. 마이크로소프트에서의 code signing 에서도 MD5 와함께표준으로사용되고있다. SHA 알고리즘은 160 비트의해쉬를만들어내기때문에, 128 비트를이용하는 MD5 에비해보안의정도가높다고할수있다. 암호화컴포넌트의활용 인터넷에보면여러가지암호화컴포넌트가프리웨어로공개되고있다. 그중에서도표준알고리즘인 DES, SHA 를비롯한여러가지알고리즘을구현한컴포넌트들을 DSP(Delphi Super Page) 나델파이델리 (Delphi Deli) 등에서구할수있다. CD-ROM 과함께제공되는 40 장디렉토리에보면, Crypt 라는서브디렉토리가있는데여기에앞으로차세대암호화알고리즘의표준으로제안되고있는 Cast, RC6, Mars 알고리즘을컴포넌트화한유닛의소스코드가포함되어있다. 이들알고리즘에대해서더자세히알고싶으면 Mars 는 http://www.reaserch.ibm.com/security/mars/, Cast 는 http://www.entrust.com/, RC6 는 http://theory.lcs.mit.edu/~rivest/ 홈페이지를방문하기바란다. 이들컴포넌트는모두 Duff Neill 에의해제작되었다. 이컴포넌트들을이용하여예제프로그램을작성할것이므로이들을컴포넌트팔레트에설치하기바란다. 그밖에도 David Barton 이 RC5, Blowfish, rmd160, RC5, Misty, IDEA, Skipjack 등의암호화기법을구현한컴포넌트를공개하였는데이를 Others 서브디렉토리에같이제공하고있다. David Barton 은델파이를이용한암호화컴포넌트페이지를운영하고있는데, 관심있는독자들은 http://web.ukonline.co.uk/david.w32/delphi.html 주소에서운영하는그의홈페이지를방문해보기바란다. 그러면, 이컴포넌트들을이용하여파일을암호화하고해독하는방법을알아보자. 먼저폼위에라디오그룹과라벨컴포넌트 2 개, 버튼 3 개를얹고 TOpenDialog, TMars, TCast, TRC6 컴포넌트와메모컴포넌트를다음과같이폼에하나씩추가한다.
그리고, 각컴포넌트의프로퍼티를앞의그림에맞도록설정한다. 여기서 Open File 버튼을클릭하면메모컴포넌트에읽어올파일을대화상자에서선택하도록한다. 그리고, Encrypt 버튼을클릭하면라디오그룹에서선택한암호화방법으로암호화하고파일의확장자가.enc 인파일로저장한다. Decoding 버튼을클릭하면확장자가.enc 인암호화된파일의내용을해독해서확장자가.dec 인파일로저장한다. 이때이런과정의내용을메모컴포넌트에서계속볼수있도록한다. TRC6, TMars, TCast 컴포넌트의사용방법은완전히동일하다. 키가될문자열을 Key 프로퍼티에설정하고, InputFile 프로퍼티와 OutputFile 프로퍼티에각각읽어올파일이름과암호화나해독과정을거쳐생성될출력파일이름을지정한뒤에암호화할경우에는 EncipherFile, 해독할경우에는 DecipherFile 메소드를호출하면된다. 먼저파일을읽어오는 Button1 의 OnClick 이벤트핸들러를다음과같이작성한다. procedure TForm1.Button1Click(Sender: TObject); if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); Label2.Caption := OpenDialog1.FileName; 여기서미리 텍스트파일 이나 모든파일 을선택할수있도록 OpenDialog1 객체의 Filter 프로퍼티를오브젝트인스펙터에서설정하도록한다. 그리고, Label2 는암호화와해독이진행되는원래파일의이름을보여주도록하는것이다. 암호화와해독을진행하도록하는 Button2 와 Button3 의 OnClick 이벤트핸들러는다음과
같이작성한다. procedure TForm1.Button2Click(Sender: TObject); case RadioGroup1.ItemIndex of 0: Mars1.Key := 'Sample Key'; Mars1.InputFile := Label2.Caption; Mars1.OutputFile := ChangeFileExt(Label2.Caption, '.enc'); Mars1.EncipherFile; 1: Cast1.Key := 'Sample Key'; Cast1.InputFile := Label2.Caption; Cast1.OutputFile := ChangeFileExt(Label2.Caption, '.enc'); Cast1.EncipherFile; 2: RC61.Key := 'Sample Key'; RC61.InputFile := Label2.Caption; RC61.OutputFile := ChangeFileExt(Label2.Caption, '.enc'); RC61.EncipherFile; Memo1.Lines.LoadFromFile(ChangeFileExt(Label2.Caption, '.enc')); procedure TForm1.Button3Click(Sender: TObject); case RadioGroup1.ItemIndex of 0: Mars1.Key := 'Sample Key';
Mars1.InputFile := ChangeFileExt(Label2.Caption, '.enc'); Mars1.OutputFile := ChangeFileExt(Label2.Caption, '.dec'); Mars1.DecipherFile; 1: Cast1.Key := 'Sample Key'; Cast1.InputFile := ChangeFileExt(Label2.Caption, '.enc'); Cast1.OutputFile := ChangeFileExt(Label2.Caption, '.dec'); Cast1.DecipherFile; 2: RC61.Key := 'Sample Key'; RC61.InputFile := ChangeFileExt(Label2.Caption, '.enc'); RC61.OutputFile := ChangeFileExt(Label2.Caption, '.dec'); RC61.DecipherFile; Memo1.Lines.LoadFromFile(ChangeFileExt(Label2.Caption, '.dec')); 이들컴포넌트의사용방법에대해서는앞에서도간단히설명하였으므로자세한설명은생략한다. 참고로 ChangeFileExt 함수는파일이름의확장자를 2 번째파라미터에지정한문자열로변경하기때문에읽어온파일의확장자를.enc 와.dec 로변경하여지정할수있다. 컴파일을하고, 이를실행한뒤에 Open File 버튼을클릭하여암호화할대상파일을선택하도록하자. 그리고, Encrypt! 버튼을클릭하면암호화과정을거쳐.enc 파일이생성되면서이파일을메모에읽어온다. 아마도다음과같이알수없는문자열이보일것이다. 이제다시 Decoding! 버튼을클릭하면해독과정을거쳐.dec 파일이생성되면서이파일을메모에읽어온다. 이과정을거치면원래텍스트파일과같은내용으로복원되는것을확인할수있을것이다.
NetMaster 컴포넌트의활용 39 장에서도이미설명한바있지만, MIME/Base 64 암호화나 UUEncoding/UUDecoding 암호화는 TNMUUProcessor 컴포넌트를이용해서수행할수있다. 앞서 UUEncoding 과 UUDecoding 을하기위한루틴을소개한바있으나, TNMUUProcessor 컴포넌트를이용하여암호화를수행하는예제를하나작성해보도록하자. 먼저폼에 TRadioGroup 컴포넌트 2 개와버튼 3 개, 그리고 TLable 컴포넌트 4 개와 TOpenDialog, TSaveDialog, TNMUUProcessor 컴포넌트를하나씩올려놓고다음과같이디자인한다.
입력파일 과 출력파일 버튼을클릭하면 Label3, Label4 에입력과출력으로사용될파 일의이름이표시되도록다음과같이 Button2, Button3 의 OnClick 이벤트핸들러를다음 과같이작성한다. procedure TForm1.Button2Click(Sender: TObject); if OpenDialog1.Execute then Label3.Caption := OpenDialog1.FileName; procedure TForm1.Button3Click(Sender: TObject); if SaveDialog1.Execute then Label4.Caption := SaveDialog1.FileName; 그리고, 실행 버튼을클릭하면라디오그룹에서선택한방법으로인코딩또는디코딩을 하도록다음과같이 Button1 의 OnClick 이벤트핸들러를작성하면된다. procedure TForm1.Button1Click(Sender: TObject); var InStream, OutStream: TFileStream; InStream := TFileStream.Create(Label3.Caption, fmopenread); OutStream := TFileStream.Create(Label4.Caption, fmcreate); try case RadioGroup1.ItemIndex of
0: NMUUProcessor1.Method := uumime; 1: NMUUProcessor1.Method := uucode; NMUUProcessor1.InputStream := InStream; NMUUProcessor1.OutputStream := OutStream; case RadioGroup2.ItemIndex of 0: NMUUProcessor1.Encode; 1: NMUUProcessor1.Decode; finally InStream.Free; OutStream.Free; 이제프로그램을컴파일하고실행한뒤에해당되는파일들의이름을지정하고, 실행 버튼 을클릭하면암호화된파일이생성되거나, 암호화된파일이해독될것이다. 인터넷보안표준 (Internet Security Standards) 인터넷이일반화되면서, 전자상거래도활발하게적용되고있다. 이러한인터넷에서도보안은매우큰문제라고할수있다. 이를위해암호화와같은보안기법이절실히요구된다. 마이크로소프트와네트스케이프브라우저에서사용하는보안프로토콜은 public-키와 private-키암호화방법의장점을모두수용하고있다. 가장널리쓰이는보안프로토콜이바로 SSL(Secure Sockets Layer) 이다. SSL 은네비게이터의첫번째버전과 IE 3.0 부터채용하고있다. 1995 년에마이크로소프트는새로운보안프로토콜을제안했는데, 이것이바로 PCT(Private Communications Technology) 이다. 이것역시 IE 3.0 에서부터채용되었다. 그밖에 IETF(Internet Engineering Task Force) 에서는 SSL 을바탕으로새로운인터넷표준보안프로토콜을제안했는데이것이 TLS(Transport Layer Security) 이다. SSL(Secure Sockets Layer) 네비게이터 3.0 과 4.0 의좌하단코너에는보안아이콘이나타난다. 네비게이터 3.0 에서는 아이콘의형태가체인의형태이고, 4.0 에서는자물쇠형태이다. 끊어진체인이연결되거나, 자물쇠가잠긴형태로바뀌면이것은서버에접근할때보안세션으로들어간다는것을의
미한다. 브라우저가보안이된웹페이지에처음접속할때에서버는 hello request 메시지를전송한다. 보안세션을시작하기위해서는브라우저가 client hello, 라고불리는메시지로반응해야하며, 서버는 server hello. 로응답해야한다. 이런초기과정에서브라우저와서버는 handshake 프로토콜을이용해서보안정보를주고받는다. 이과정이 SSL 의첫번째파트이다. 클라이언트의 hello 메시지는세션 ID 라는숫자를가지고있는데, 이를이용해서브라우저와서버간의세션을나타낸다. 또한, 메시지는서버에게어떤암호화알고리즘을쓸것인지, 그리고 SSL 의버전과브라우저가지원하는압축방법등을알려준다. 마지막으로브라우저가생성해낸난수를포함한다. 서버 hello 메시지는브라우저에의해제공되는것들중에서압축방법과암호화알고리즘, 적절한 SSL 버전과다른난수, 가능한세션 ID 등을선택해서반응하게딘다. 이단계에서클라이언트와서버는디지털 certificate 를서로교환하게되는데, 이를통해서로의내용을확인하게된다. 서버의 certificate 에는 handshake 프로토콜에서선택된 public-키암호화알고리즘에적합한 public 키를포함하며, 이키가짧은시간이용된다. 그렇지만, 실제적인트랜잭션은 private-키암호화기법을이용해서암호화된다. 이를구현하기위해서서버와클라이언트는브라우저에의해생성된하나의 private 키를가지고, 서버로의전송을위한마스터키로 public 키만을사용하는것이아니라브라우저가 premaster secret 키를대신보낸다. 이미정의된프로토콜에따라서버는 premaster secret 키를이용하여실제마스터키를결정한다. 이렇게함으로써실제마스터키를전송할필요가없게되며, 이런프로세스가완료되면브라우저와서버는마스터키의복사본을가지게된다. 인터넷익스플로러보안 (Internet Explorer Security) IE 3.0 은 SSL 과 PCT 를모두지원한다. PCT 는 SSL 과마찬가지로 private 키를암호화할때 public 키암호를사용하는방식을이용한다. SSL 과 PCT 의가장큰차이점은바로 handshake 프로토콜단계에있다. PCT 는호환가능한프로토콜과접속하기위해보다적은수의메시지를요구하며, 더많은암호화알고리즘을지원한다. 또한, 인증 (authentication) 과암호화에서로다른키를사용함으로써보안의정도가높다. IE 4.0 에서는이밖에도자체적인보안구역 (security zone) 을이용하여사용자가자신의브라우저의보안레벨을조절할수있도록하고있다. 각각의보안구역에특정행동만할수있도록보안레벨을부여할수있다. 예를들어, 회사의인트라넷사이트를 trusted zone 으로설정하면특별한암호화를거치지않고이사이트와통신할수있다. 반대로처음으로방문하는인터넷사이트를 untrusted zone 을설정하면, 항상서버에게브라우저가정보를보내기전에 SSL 인증을할것을요구하게된다.
인터넷보안의미래 TLS (Transport Layer Security) TLS 프로토콜은 SSL 에기초한프로토콜로앞으로표준이될가능성이높다. 참고로신용카드회사를중심으로새로운보안표준을개발하고있는데, 이것이 SET(Secure Electronic Transaction) 표준이다. SET 는 TLS 와같은프로토콜과함께사용할수있으며, 인증과신뢰성에초점을맞춘프로토콜이다 정리 (Summary) 이번장에서는가장기본적인보안을유지하기위해간단한암호화방법에서부터현재표준적으로사용되고있는몇가지알고리즘을소개하고, 차세대암호화표준알고리즘으로제안되고있는알고리즘을구현한컴포넌트를이용하여간단한예제를작성해보았다. 그리고, 인터넷에서제안되고있는몇가지암호화에관한프로토콜을소개하였다. 최근에이런암호화와보안의중요성은날이갈수록강조되고있다. 물론제대로된보안을위해서는하드웨어적인보안과설비등이필요하고고려해야될요소가많지만, 의외로앞에서설명한간단한방법으로도웬만한수준의보안은유지할수있으므로조금만더신경을써서어플리케이션을마무리할것을권하는바이다.