◇ 간단한 암호화 소스 ◇
글: 박후선(OSOLGIL)
osolgil@pop.chollian.net
softech@soback.kornet.nm.kr
본 소스 코드에 사용되는 암호화 알고리즘은 Encrypt와 Decrypt가 가능한 것이
다. 즉, Encrypt를 통해 암호화를 걸고 Decrypt를 통해 암호를 해독하는 것이 가
능하다. 이렇게 해독기능을 부여하는 것은 여러 종류의 어플리케이션들에서 유용
할 수 있다.
단지, 사용자의 암호를 암호화 하여 저장하는 것이라면 Decrypt는 필요치 않다.
하지만 간단한 예로, 웹서버 어플리케이션 제작에서의 쿠기(Cookie) 사용을 생각
해 보자. 쿠키는 웹 브라우져에 따라 어떤 형태로던 사용자 컴퓨터의 하드디스크
어딘가에 저장된다. 이 쿠키는 아주 간단히 열어서 내용을 파악할 수 있으므로
이 내용을 암호화 할 필요가 있다. 다음으로, 웹서버 어플리케이션이 이 쿠키를
이용하기 위해서는 쿠기를 읽어서 암호를 해독해야 원본 데이터를 알 수 있다.
Encrypt와 Decrypt를 지원하는 이 소스코드는 원래 볼랜드 사이트에서 받았던 것
으로 본인이 다시 수정을 가한 것이다. 이 암호화 소스는 3개의 키를 쓴다. 키
두 개는 소스코드에 넣어두고 Encrypt를 걸 때 다른 한키를 인자로 준다.
Decrypt에서도 키를 인자로 받는데, 이 때 키 값이 다르다면 해독은 불가능하다.
3개의 키를 이용하므로 경우의 수를 생각해 볼 때, 키 값을 모르면 해독이 99.9%
불가능하다. C1, C2 상수로 되어있는 기본 키 값 두 개를 여러분의 필요에 따라
변경하기 바란다. 이 두 개의 키 값은 어플리케이션 마다 다르게 주는 것이 좋을
것이다.
이 소스코드를 통해 다음과 같이 데이터가 변환된다.
원본: 'VTOOL 동호회 델파이 강좌'
Encrypt: '63AA24F1B6263E8F303F77D7364C495DFA7C3E84D84390C2'
Decrypt: 'VTOOL 동호회 델파이 강좌'
원래의 소스에는 Encrypt시의 데이터가 0-255값으로 이루어져 있었으나 필자가
Hex값으로 변환하는 루틴을 끼워넣었다. 이유는 0-255값 중 일반 TEXT 포맷으로
읽을 수 없는 컨트롤 값이 있고, 이런 것들은 Registry나 INI등에 저장하는데 문
제가 있기 때문이다.
외부에서 사용할 수 있는 두 개의 함수가 있다.
function Encrypt(const S: String; Key: Word): String;
문자열 데이터의 암호화는 Encrypt 함수를 통해 이루어진다. 인자 S로는 암호화
할 문자열를 준다. 그리고 Key에는 0..65536 사이의 키 값을 준다. 이 키 값은
Decrypt시 동일한 키 값을 주어야 한다. 함수를 호출하면 복귀값으로 Hex인 문자
열이 돌려진다.
function Decrypt(const S: String; Key: Word): String;
암호화된 문자열의 해독은 Decrypt 함수를 통해 이루어진다. 인자 S로는 암호화
된 문자열을 준다. Key에는 0..65536 사이의 값을 주는데 Encrypt에서 사용한
Key 값과 동일한 값을 주어야 한다. 복귀값으로 해독된 문자열이 돌아온다.
아래의 소스코드를 UEncrypt.pas로 저장하라. 다음 강좌에서 이것을 이용한 예제
를 올리도록 하겠다.
unit UEncrypt;
interface
function Encrypt(const S: String; Key: Word): String;
function Decrypt(const S: String; Key: Word): String;
implementation
uses SysUtils;
const
C1 = 74102;
C2 = 12337;
HexaChar : array [0..15] of Char =
( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' );
// Byte로 구성된 데이터를 Hexadecimal 문자열로 변환
function ValueToHex(const S : String): String;
var
I : Integer;
begin
SetLength(Result, Length(S)*2); // 문자열 크기를 설정
for I := 0 to Length(S)-1 do
begin
Result[(I*2)+1] := HexaChar[Integer(S[I+1]) shr 4];
Result[(I*2)+2] := HexaChar[Integer(S[I+1]) and $0f];
end;
end;
// Hexadecimal로 구성된 문자열을 Byte 데이터로 변환
function HexToValue(const S : String) : String;
var
I : Integer;
begin
SetLength(Result, Length(S) div 2);
for I := 0 to (Length(S) div 2) - 1 do
begin
Result[I+1] := Char(StrToInt('$'+Copy(S,(I*2)+1, 2)));
end;
end;
// 암호걸기
function Encrypt(const S: String; Key: Word): String;
var
I: byte;
FirstResult : String;
begin
SetLength(FirstResult, Length(S)); // 문자열의 크기를 설정
for I := 1 to Length(S) do begin
FirstResult[I] := char(byte(S[I]) xor (Key shr 8));
Key := (byte(FirstResult[I]) + Key) * C1 + C2;
end;
Result := ValueToHex(FirstResult);
end;
// 암호풀기
function Decrypt(const S: String; Key: Word): String;
var
I: byte;
FirstResult : String;
begin
FirstResult := HexToValue(S);
SetLength( Result, Length(FirstResult) );
for I := 1 to Length(FirstResult) do
begin
Result[I] := char(byte(FirstResult[I]) xor (Key shr 8));
Key := (byte(FirstResult[I]) + Key) * C1 + C2;
end;
end;
end.
-- 출처 --