더 큰 세상으로 가는 문 액티브X 대체기술

 

기획/정리 l 전희용 기자 flytgr@imaso.co.kr

 

마소 독자치고 액티브X 문제와 무관하다고 할 수 있는 사람은 별로 없을 것이다. 그런데, 참 이상한 일은 액티브X 이야기만 나오면 문제의 원인이나 해결책을 이야기하기 보단 목에 핏대부터 세운다. 누군가를 탓하기 위함이다. 하지만 막상 따지고 보면 누구의 잘못이라고 하기는 어려운 일이다. 워낙 오랫동안 쌓아온 일이기 때문이다.
그렇다고 곪을 대로 곪은 상처를 그냥 놓아둘 수도 없는 일. 이번 달 특집에서는 이 상처의 원인에 대해 알아보고, 그 치료방법인 액티브X의 대체 기술들에 대해서도 함께 알아본다. 다들 잘 알다시피 아직 액티브X를 1대1로 대신해 줄 수 있는 기술은 없다. 하지만, 여러 기술들을 이용하여 산적한 문제들을 보완하며 차츰 치료해 나갈 수는 있을 것이다. 깊이 박힌 상처가 하루아침에 낫는 걸 보았는가?

 

1부 | 백조에서 미운오리로 전락한 액티브X 문제와 해결방안 | 정희용

2부 | 발등의 불끄기 공인인증서 대체기술 | 최상훈

3부 | UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발 | 박영록

4부 | 액티브X 뛰어넘는 기능과 호환성 XPCOM 개발전략 | 김민수

5부 | MS가 내놓은 액티브X의 대안 실버라이트 활용법 | 한용희

 

MS가 내놓은 액티브X 컨트롤의 대안 실버라이트 활용법

 

최근 정부기관들이 앞장서서 액티브X의 배제에 노력하면서 사회 전반에서도 액티브X에 대한 관심이 뜨겁다. 정부기관의 노력으로는 신규 발주 사업의 제안 요청서에 특정 제품을 지원하지 않도록 명시하여 표준을 따르지 않는 기술의 제안을 차단하는 것 등이다.
5부에서는 액티브X 컨트롤의 대안으로 MS가 내놓은 실버라이트 활용법에 대해 알아보자.

 

한용희 | woom33@korea.com | 롯데정보통신 정보기술연구소에 재직 중

 

요즘은 브라우저 하나만 있으면 거의 모든 작업을 할 수 있다. 기업 내에서 사용하는 ERP 애플리케이션도 브라우저 하나로 돌아가고 은행 거래나 쇼핑, 공공기관 증명서 발급 등 모든 작업을 브라우저 안에서 할 수 있다. 하지만 이는 브라우저가 가진 기본적인 기능에서 액티브X 컨트롤을 이용하여 그 능력을 확장했기에 가능한 기능들이다.

이에 따라 이제는 기존 브라우저가 가진 단순 정보 표현 기능 말고도 사용자의 새롭고 다양한 욕구를 충족시켜줄 수 있는 새로운 프레임워크가 필요하다. 시대는 그러한 기능을 요구했고, 사람들은 그러한 기능을 수행할 수 있는 새로운 대안을 찾아 다녔다. 그렇다고 기존에 웹이라는 세상이 만들어 놓은 네트워크 구조를 무너뜨릴 생각은 없었다. 오히려 이를 그대로 이용하면서 그 위에서 다양한 기능을 수행 할 수 있는 무엇인가가 필요했다.

그래서 찾은 것이 단순 애니메이션 기능으로 사용하였던 플래시였다. 플래시는 브라우저 위에 액티브X 컨트롤로 만들어진 별도의 플러그인을 한 번만 설치하면 플래시로 만든 모든 응용 프로그램을 구동할 수 있다. 즉, 새로운 기능을 제공하는 새 프레임워크를 발견한 것이다. 사람들은 이 플래시를 단순 애니메이션 도구가 아닌 새로운 응용 프로그램을 만들 수 있는 도구로 재평가하기 시작했고, 플래시는 그러한 기능을 하나 둘씩 추가해 나갔다.

플래시는 본격적인 응용프로그램 개발 툴로 끌어올린 플랙스(FLEX)라는 제품을 발표하면서 본격적으로 리치 인터넷 애플리케이션(Rich Internet Application) 서비스를 하게 된 것이다.

액티브X 컨트롤을 대체하려면 무엇보다 브라우저가 가진 기능을 확장할 수 있어야 하며, 웹이 만들어 놓은 네트워크라는 세상 안에서 그 기능을 수행해야만 한다. 또한 특정 OS나 특정 브라우저가 아닌 모든 환경에서 사용가능 해야만 한다. 이러한 조건을 충족시키기 위해서는 기존 브라우저 위에서 플래시처럼 한 번의 플러그인을 설치하면 모든 응용 프로그램을 구동시킬 수 있는 기술이 필요했던 것이다. 그래서 탄생한 것이 바로 실버라이트(코드명: WPF/e)이다.

플래시와 비슷한 개념이고 기능도 비슷하지만 내부를 들여다보면 그 개발 환경은 사뭇 다르다. 플래시는 태생이 애니메이션을 위한 도구로 출발한 것인 반면에 실버라이트는 출발부터 디자이너와 개발자를 위한 새로운 플랫폼으로 출발한 기술이다.

 

 

개발자와 디자이너를 위한 협업

 

개발자와 디자이너는 서로 다른 세계를 살아가는 사람들이다. 개발자가 숲 보다는 나무를 보고 일하는 사람이라면 디자이너는 나무 보다는 숲을 보고 일하는 사람들이다. 서로의 보는 관점 자체가 다르다. 이렇게 서로 다른 시각을 가진 사람들이 일을 하다보면 서로 의사소통이나 표현의 문제로 서로 대립되는 경우도 비일비재하다.

이러한 문제가 가장 크게 대두 되면서 만연했던 시기가 바로 ASP 시절이다. 일면 스파게티 코드로 유명한 ASP 코드는 디자이너의 코드와 개발자의 코드가 뒤섞여 있다. 자고 일어나면 상대방이 수정을 해서 디자인이 헝클어지거나 기능이 제대로 동작하지 않는 경우가 있었다. 이럴 때면 서로 네 탓이니 내 탓이니 하면서 싸우기 일쑤였다.

이러한 문제는 ASP.NET 기술이 디자이너의 코드와 개발자의 코드를 분리하면서 어느 정도 해결되었다. 하지만 사용자의 편의성을 높이기 위한 기능들은 클라이언트 쪽에서 구동되어야 하는데, 이는 별도의 스크립트라는 언어로 개발을 해야만 했다. 디자이너는 자신의 상상 속에서 사용자의 편의성을 높이기 위한 디자인을 내 놓지만 개발자가 디자이너의 그러한 상상의 세상을 스크립트로 구현하기란 좀처럼 쉽지 않았다. 그래서 디자이너와 개발자의 중간에 위치한 UI 개발자라는 별도의 직업까지 생길 정도였다.

사용자의 요구사항은 이제 점점 웹을 단순한 정보를 표현하는 도구가 아닌 사용자와 서로 편하게 대화할 수 있는 환경으로 만들어 주기를 원했다. 이제 웹은 정보를 보여주는 도구가 아닌 정보를 생산하는 도구가 된 것이다. 따라서 사용자의 UI를 편하게 만드는 것이 보다 좋은 웹사이트를 만드는 척도가 되었다.

이제는 디자이너가 꿈꾸고 있는 상상속의 이미지를 그대로 표현해 주는 새로운 기술이 필요해 졌다. 기존의 HTML은 정보를 보여주는 데 적절한 언어이지 정보를 생산하는 데에는 적합하지 않았다. 따라서 HTML이 아닌 다른 새로운 표준이 필요했고 그래서 나온 것이 바로 XAML(eXtensible Application Markup Language, 재믈)이다. 이를 통해서 디자이너가 생각하는 기능과 표현을 XML 기반의 새로운 태그 언어로 표시한 것이다. XAML에 대해서는 자세히 설명하지는 않을 것이다. 이미 여러 차례 마이크로소프트웨어에서 소개되었기 때문이다(2007년 1월호 특집 기사 참조).

이제 디자이너는 XAML을 생성해 주는 새로운 도구를 이용해서 디자인을 해야만 한다. 그래서 MS에서는 익스프레션 제품군을 새로 만들어 판매하고 있다. <표 1>은 2007년 1월호 특집 기사에 실린 익스프레션 제품군과 어도비의 디자인 프로그램 비교표이다.

Microsoft
Adobe
익스프레션 디자인
일러스트레이터
포토샵
익스프레션 블랜드
플래시
플렉스
익스프레션 웹
드림위버
익스프레션 미디어
프리미어

<표 1> MS와 어도비의 디자인 제품 비교표

새로운 툴로 전향하기 싫은 사람들을 위해서도 별도의 변환 툴을 제공한다. 현재는 다음과 같은 두 가지 변환 도구가 출시되어 있다.

· SWF to XAML Converter(http://www.mikeswanson.com/ swf2xaml)
: 플래시 SWF 파일을 XAML 파일로 변환

· Adobe Illustrator to WPF/XAML Export Plug-In(http://www.mike swanson.com/xamlexport)
: Illustrator에서 XAML 파일로 저장해주는 플러그 인

MS에서는 이렇게 사용자의 편의성을 높여주는 일련의 활동을 UX(User Experience, 사용자 경험)라고 정의하고 있다. 이제 디자이너는 마음껏 사용자의 편의성을 향상시키기 위하여 자신만의 언어를 사용할 수 있게 되었으며, 개발자도 자연스럽게 이를 수용할 수 있는 준비가 된 것이다.

 

 

웹을 위한 종합선물세트, 실버라이트

 

요즘 기술 트렌드를 대변 하는 말 중에 유행하는 말이 한 가지 있다. 그것은 바로 ‘종합선물세트’라는 것이다. 요즘 기술의 추세는 특정한 기능에 편중되지 않고 모든 기능을 포함하는 것이 유행이다. 필자가 처음 실버라이트의 아키텍처를 보고 제일 먼저 머리에 떠오른 단어도 ‘종합선물세트’이었다. 실버라이트는 요즘 유행하는 모든 기술을 거의 다 담았다고 해도 과언이 아니다. 실버라이트는 현재 두 가지 버전이 있다. 1.0 베타와 1.1 알파 버전이다. 1.0 버전은 올 여름에 출시될 예정이고, 1.1 버전은 아직 미정이다. 1.0과 1.1의 가장 큰 차이점은 1.1에서는 닷넷 프레임워크 프로그래밍 모델을 지원한다는 것이다. 즉, C#이나 비주얼 베이직을 이용하여 관리코드(Managed Code)를 작성할 수 있다. 닷넷 프로그래밍 모델을 지원하면 앞으로 실버라이트의 개발이 훨씬 용이해 질 것이다. 1.0 버전에서는 자바 스크립트만 지원한다. 이제 실버라이트의 주요 특징을 차례로 알아보자.


<그림 1> 실버라이트 Application structure

크로스 브라우저(Cross-browser), 크로스 플랫폼(Cross-platform)
실버라이트의 가장 큰 특징은 한 마디로 크로스 브라우저와 크로스 플랫폼이다. 현재 지원 가능한 브라우저는 IE와 모질라, 파이어폭스, 애플 사파리와 오페라다. 운영체제는 윈도우와 애플의 Mac OSX를 지원한다.

경량화(Lightweight browser plug-in)
이름에서도 알 수 있듯이 실버라이트의 브라우저 플러그인은 경량화를 지향한다. 현재 실버라이트 1.0 베타 버전의 런타임은 1.38MB정도 한다. 최종 런타임도 3MB를 넘지 않을 것이라고 한다. 참고로 플래시 9.0의 런타임은 현재 2.2MB이다.

멀티미디어 지원
실버 라이트는 오디오와 비디오 재생을 위한 자체적인 스트리밍 플레이 기능을 가지고 있는 덕분에 별도의 플레이어 없이 자체적으로 재생할 수 있다. 비디오는 윈도우 미디어 콘텐츠인 WMV와 WMA 포맷을 지원하며, HDTV 수준의 비디오 해상도도 지원한다. 오디오로는 MP3 포맷을 지원한다. 현재 www. Silverlight.net 사이트에 가면 폭스 무비(Fox Movie)의 영화 예고편을 실버라이트로 만들어 놓은 것을 확인해 볼 수 있다. 상당한 수준의 해상도를 지원하는 영화 예고편을 감상 할 수 있다.

WPF, XAML 지원
실버라이트는 프레젠테이션 기술로 WPF(Windows Presentation Foundation)를 채택하였다. WPF는 윈도우 비스타의 닷넷 프레임워크 3.0에 포함된 기술인데, 디자인을 표현하는데 있어 XAML을 이용한다. 이에 대한 자세한 내용 역시 2007년 1월호 특집 기사를 참고하길 바란다. 실버라이트의 초창기 코드명은 WPF/e였다. 여기서 e는 Everywhere 즉, 어디서나 WPF 응용프로그램을 사용하자는 취지로 만들어진 코드명이다. 때문에 실버라이트는 3D 기능을 제외한 대부분의 WPF 기능을 제공한다. 플래시와 마찬가지로 벡터 기반이기 때문에 확대하거나 축소를 하더라도 이미지의 손실 없이 부드럽게 표현되는 것도 빼놓을 수 없는 특징이다.

닷넷 프로그래밍 모델 지원
실버라이트 1.1버전부터는 닷넷 프로그래밍 모델도 지원한다. CLR 전부를 지원하는 것은 아니지만, CLR 대부분의 기능을 지원할 예정이다. 사용 할 수 있는 언어로는 C#과 비주얼 베이직, IronPython, Ruby, Managed JScript 등이 있다. 이중에 C#과 비주얼 베이직은 기존에 있던 언어이지만 새롭게 동적 언어인 IronPython, Ruby, Managed JScript 지원을 추가했다. 스크립트 언어가 가진 높은 생산성을 더 이상 무시할 수 없었던 것이다. 현재 ASP.NET도 IronPython과 같은 동적언어를 추가할 예정이다(http://www.asp.net/downloads/futures/default. aspx?tabid=62).

기존 응용프로그램 지원
실버라이트는 자바스크립트와 서로 연동할 수 있다. 자바 스크립트 뿐만 아니라 ASP.NET AJAX와도 쉽게 연동할 수 있다. 한 예로 http://www.thewpfblog.com/examples/wpfe/microbe /Default.html에 가면 WPF/e와 플래시가 서로 연동되는 데모를 볼 수 있다. 공이 튀는 하나의 화면에서 움직이는 것 같지만 사실 왼쪽은 WPF/e로 만든 것이고, 오른쪽은 플래시로 만든 것이다. 서로 데이터를 주고받으면서도 부드러운 움직임을 보여준다.


<화면 1> WPF/e와 플래시가 서로 연동한 데모

압축 지원
XAML 파일은 텍스트 기반이기 때문에 그 용량이 상당히 크다. 따라서 이를 그대로 웹에 올리려면 용량이 문제가 된다. 플래시의 경우도 개발 시에는 FLA 파일 포맷을 사용하지만 실제 배포할 때에는 압축된 SWF 포맷을 사용한다. 실버라이트도 이러한 압축 기술을 지원할 예정이다.


<그림 2> 실버라이트의 압축 패키징

 

 

실버라이트와의 조우, Hello World!

 

새로운 언어를 배울 때 언제나 등장하는 것이 바로 ‘Hello World’를 출력하는 예제일 것이다. 실제로 이 예제를 만들어 봄으로써 실버라이트의 개발 환경을 느껴보자. 실버라이트를 개발하는데 있어 여기에서는 1.1 알파 버전을 사용할 것이다. 1.0 버전 버전은 닷넷 프레임워크를 아직 지원하지 않기 때문에 다양한 기능을 보여주기에는 부족한 점이 있다.

1.1 알파 버전은 http://msdn2.microsoft.com/en-us/asp. net/bb187452.aspx에서 다운로드 받아서 설치하면 된다. 웹 페이지에 접속하면 다음과 같은 프로그램들 목록이 표시된다.

· Microsoft Silverlight 1.1 Alpha.브라우저 플러그 인
· Microsoft Silverlight 1.1 Alpha Software Development Kit(SDK)개발 툴 킷
· Microsoft Expression Blend 2 PreviewXAML 디자인을 위한 디자인 툴
· Microsoft Visual Studio Code Name “Orcas” Beta 1.비주얼 스튜디오 차기 버전인 Orcas Beta1 버전
· Microsoft Silverlight Tools Alpha for Visual Studio Code Name “Orcas” Beta 1.Orcas Beta1 버전에서 실버라이트를 개발하기 위한 프로젝트 템플릿

설치할 프로그램이 많은 편이다. 이 프로그램들은 모두 무료로 다운로드 받을 수 있으므로 전부다 다운로드 받아서 설치를 한다.
먼저 C# 기반의 실버라이트 응용 프로그램을 만들어 보자. 비주얼 스튜디오를 실행하고 새 프로젝트에서 C# 밑에 있는 실버라이트 프로젝트를 선택한다.


<화면 2> 실버라이트 프로젝트 선택하는 화면

프로젝트를 생성하면 <화면3>과 같은 프로젝트가 만들어 진다.


<화면 3> C# 기반의 실버라이트 프로젝트

화면을 표시하는 페이지는 TestPage.html이다. 기존의 MS 방식대로라면 확장자를 htm으로 사용하겠지만, html을 사용한 것으로 봐서는 크로스 브라우저를 지향하려는 의도가 엿보인다. TestPage.html 코드를 보면 별다른 코드가 없다.

<리스트 1> TestPage.html의 일부

<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="TestPage.html.js" ></script>
...

<body onload="document.getElementById('Silverlight Control').focus()">
<div id="SilverlightControlHost" >
<script type="text/javascript">
createSilverlight();
</script>
</div>
</body>

실버라이트의 런타임 자체도 액티브X 컨트롤로 만들어져 있는데, 작년에 이올라스 패치 문제가 있었듯이 한 파일 안에서 같이 실행하면 액티브X 컨트롤이 활성화되지 않는 탓에 별도의 파일로 분리하는 것이 좋다. Silverlight.js 파일은 모든 브라우저에서 실버라이트가 동작하도록 만들어 놓은 자바스크립트 라이브러리다. TestPage.html.js는 Silverlight.js에 있는 실버라이트 생성 컨트롤을 호출하면서 XAML 파일을 연동시켜주는 역할을 한다.

<리스트 2> TestPage.html.js

function createSilverlight()
{
Sys.Silverlight.createObjectEx({
source: "Page.xaml",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
width: "100%",
height: "100%",
version: "0.95",
enableHtmlAccess: true
},
events: {}
});
}

Page.xaml 파일을 보면 단순히 Canvas 하나를 그리는 구문만이 존재 한다.

<리스트 3> Page.xaml

<Canvas x:Name="parentCanvas"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Page_Loaded"
x:Class="HelloWorld_CS.Page;assembly= ClientBin/HelloWorld_CS.dll"
Width="640"
Height="480"
Background="White"
>
</Canvas>

이 구문에서 x:Class라는 부분이 바로 닷넷 프로그래밍 모델로 만든 어셈블리를 연동하는 부분이다. 클래스명과 경로를 적어주어야 한다. DLL로 만든 클래스의 네임스페이스와 이름을 표기하고 실제 DLL 파일의 경로를 적어 준다. Loaded에는 초기에 로드 되면서 호출할 메소드 이름을 적어준다.

디자이너는 이 XAML 파일을 수정하고 개발자는 이 XAML에 연동된 파일(여기에서는 xaml.cs)을 각각 수정하면 된다.

<리스트 4>Page.xaml.cs

namespace HelloWorld_CS
{
public partial class Page : Canvas
{
public void Page_Loaded(object o, EventArgs e)
{
// Required to initialize variables
InitializeComponent();
}
}
}

현재까지는 각각의 코드가 아무런 일도 하지 않는다. 이제 익스프레션 블랜드를 이용해서 Hello World! 텍스트 박스 하나를 그려보자.
<화면 4>처럼 비주얼 스튜디오에서 바로 블랜드를 호출할 수 있다.


<화면 4> Blend를 여는 메뉴


<화면 5> Hello World! 텍스트 박스를 추가한 모습

<화면 5>를 보면 Hello World! 텍스트 박스를 추가한 모습을 볼 수 있다. 블랜드에서는 비주얼 스튜디오와 마찬가지로 옆에 프로젝트 리스트가 나오며 블랜드에서 아예 프로젝트를 새로 만들 수도 있다. 이러한 기능은 개발자와 디자이너가 보다 긴밀하고 효과적인 협업을 할 수 있도록 만들어진 기능이라고 할 수 있다.


<화면 6> 블랜드에서 프로젝트 만들기

이제 저장을 하고 비주얼 스튜디오로 돌아와서 실행을 하면 Hello World! 텍스트가 잘 나올 것이다. 단 아직 한글 지원이 미비한 관계로 블랜드에서 언어 관련 코드는 삭제해 주어야만 한다.

<리스트 5> Page.xaml에 Hello World! 텍스트 박스 추가한 결과

<TextBlock Width="156" Height="37" Canvas.Left="133" Canvas.Top="23" TextWrapping="Wrap">
Hello World!
</TextBlock>


<화면 7> Hello World!를 실행한 화면

이번에는 디자이너 부분이 아닌 개발자 부분에서 코드를 수정해 보자. 위의 TextBlock에 이름을 다음과 같이 지정한다.

<TextBlock x:Name=“block” Width=“156” Height=“37” Canvas.Left=“133” Canvas.Top=“23” TextWrapping=“Wrap”>
Hello World!
</TextBlock>

이를 Page.xaml.cs 코드에서 다음과 같이 수정해 보자.

block.Text = “Welcome to the Silverlight”;

즉, Page_Loaded 이벤트에서 block이라는 이름의 TextBlock의 내용을 바꾸었다. 이를 실행해 보면 Hello World!에서 ‘Welcom to the Silverlight’로 바뀐 것을 볼 수 있을 것이다.

이번에는 IronPython을 이용해서 똑같은 결과물을 만들어 보자. 위의 Page.xaml에서 동적언어에 대한 내용을 <리스트 6>과 같이 추가한다.

<리스트 6> 동적언어 지원을 위한 Page.xaml

<Canvas x:Name="parentCanvas"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640"
Height="480"
Background="White"
>
<x:Code Source="Page.xaml.py" Type="text/ironpython" />
<TextBlock Loaded="OnLoad" x:Name="block" Width="156" Height="37" Canvas.Left="133"
Canvas.Top="23" TextWrapping="Wrap">
Hello World!
</TextBlock>
</Canvas>

이번에는 닷넷 프레임워크 어셈블리가 필요 없으므로 x:Class도 선언할 필요가 없다. 대신 x:Code라는 태그를 통해서 동적언어를 설정한다. 기능은 앞의 예제와 동일하게 텍스트의 내용을 바꾼다.

<리스트 7> Page.xaml.py

def OnLoad(sender, e):
block.Text = "Welcome to the Silverlight"

결과를 보면 파이썬으로 만들어도 동일한 결과를 볼 수 있다. 그렇다면 ASP.NET처럼 이러한 관리코드나 동적코드는 서버 사이드에서 실행되는 것일까? 우리가 어떤 버튼을 클릭하면 서버에 가서 그 이벤트를 처리하고 결과를 돌려주는 방식일까? 그것은 아니다. 실버라이트는 어셈블리나 동적언어 코드를 직접 클라이언트에 모두 로딩 한다. 따라서 서버에 특정 네트워크 통신을 따로 하지 않는 이상 라운드 트립은 없다.

 

 

실버라이트의 추가적인 특징들

 

실버라이트의 주요 특징과 간단한 샘플 프로그램도 만들어 보았다. 이번에는 실버라이트의 추가적인 특징들에 대해 알아보자.

DRM(Digital Right Management)
콘텐츠에 대하여 DRM 기능을 쉽게 적용할 수 있도록 지원되는 기능이다. 이를 이용하면 자신의 실버라이트의 콘텐츠에 대하여 저작권 보호 기능을 사용할 수 있다. 아직 구체적인 예제는 없지만, 예를 들면 복사를 제한하는 등의 기능이 추가될 것으로 예상된다.

LINQ(Language Integrated Query)
LINQ에 대해서는 2006년 1월호 ‘C#의 미래’라는 글을 참고하길 바란다. 간단히 설명하자면 DB나 XML과 같은 데이터의 쿼리 구문을 수행하는데 있어 기존에는 문자열을 조합하여 쿼리 구문을 만들거나 별도의 객체를 이용해서 쿼리 구문을 수행하였다. 쿼리 구문이 언어와 독립적인 탓에 통일성 있는 개발이 어려웠던 반면에, 이제는 이러한 쿼리 구문 자체를 언어에 포함시켰다. 따라서 이제는 쿼리 구문을 언어 차원에서 보다 쉽게 만들 수 있는 것이다. 현재 이 기능은 C#3.0에 포함될 예정이다. 비주얼 스튜디오 Orcas에는 이 기능이 이미 들어있다.

격리된 스토리지(Isolated storage)
로컬 파일 시스템에 어떤 데이터를 저장해야 할 경우가 있을 것이다. 이때 아무 폴더나 접근 가능하게 하면 기존 액티브X 컨트롤의 보안 문제와 같은 위험을 내포하게 된다. 따라서 안전하게 격리된 별도의 저장 공간을 사용함으로써 이에 따른 보안 이슈를 해결할 수 있다. 실버라이트에서는 이러한 별도의 독립적인 저장 공간인 Isolated storage를 지원한다. Isolated storage에 대해서는 http://msdn2.microsoft.com/en-us/library/ ffbfac6a-5c25-41de-830b-b7d0c1225f83.aspx을 참조하거나 2006년 7월호 ‘Enterprise Library2.0’기사를 참고하기 바란다.

파일 관리
안전한 파일 열기 다이얼로그 박스를 지원한다. 실버라이트는 HTTP POST를 이용한 웹서비스도 지원하므로 파일 업로드/다운로드 기능을 구현할 수 있다. 실제로 실버라이트 1.1 Quick Starts 샘플에 보면 파일 업로드 다운로드 샘플이 있다. 기존에 많은 파일 업로드/다운로드 기능들이 액티브X 컨트롤로 구현이 되어 있는데, 앞으로 실버라이트를 이용한 업로드/다운로드 컨트롤의 가능성에 대해서도 검토해 볼 수 있을 것이다.

JSON 지원
JSON은 JavaScript Object Notation의 약자이다. 한마디로 자바스크립트에서 사용하는 객체 기술 방법이다. XML과 비슷하게 텍스트 기반의 트리형식으로 데이터를 표시한다. XML은 범용 적이긴 하지만 파싱을 하기 위한 부하가 있고 수많은 꺽쇠 기호‘<’, ‘>’로 인하여 사이즈가 크다. 그래서 등장한 것이 경량화 되고 자바스크립트에서 바로 객체로 인식 가능한 데이터 형식인 JSON이다. 플랫폼에 종속적이지 않기 때문에 어디에서나 자유롭게 사용할 수 있다. 보다 자세한 내용은 http://www.ietf.org/ rfc/rfc4627.txt?number=4627을 참조하길 바란다.

POX 지원
POX는 Plain Old XML의 약자이다. XML 데이터를 주고받는데 있어 일반적으로는 SOAP 프로토콜을 이용한 방식이 권장된다. 하지만 SOAP 프로토콜은 부가적인 정보를 많이 포함해야 하므로 상당히 무겁다. POX는 단순한 XML 데이터를 전송하므로 상대적으로 가벼워지는 효과가 있다. 따라서 SOAP 프로토콜이나 WS-* 표준에 해당하는 기능을 사용하지 않을 거라면 단순한 POX 방식의 메시지가 유용할 것이다.

XML 라이브러리
스크립트에서 XML DOM 객체를 이용해서 XML 데이터를 처리하는 것은 쉬운 일이 아니다. 실버라이트는 닷넷 프레임워크를 그대로 사용할 수 있으므로 닷넷 프레임워크에 있는 XMLReader나 XMLWriter 클래스를 바로 사용할 수 있다. 또한 XLinQ 기능을 이용하면 보다 쉬운 쿼리 구문도 만들 수 있다.

 

 

실버라이트의 성능

 

실버라이트의 그래픽 렌더링 성능에 대해 벤치마크 할 수 있는 재미있는 사이트가 있다. 바로 http://bubblemark.com다.

여러 개의 공을 표시하고 렌더링 하면서 초당 몇 프레임이 나오는지 계산하는 프로그램이다. 동일한 프로그램을 DHTML이나 플래시, 실버라이트를 이용해서 테스트를 수행할 수 있다. 실제로 사용자가 직접 할 수 있으므로 상당히 흥미로운 사이트다. 필자가 직접 테스트한 결과도 있는데 <표 2>는 올해 2월에 WPF /e로 수행한 결과이다.


<화면 8> 실버라이트, DHTML, Flex 그래픽 렌더링 성능 테스트

결과를 보면 실버라이트의 렌더링 성능이 플렉스 못지않음을 확인할 수 있을 것이다. 이 결과 외에 여러 사람들이 테스트한 결과를 댓글로 올려놓았다. 관심 있는 독자들은 참고하길 바란다.

 

 

실버라이트의 미래

 

WPF의 부분 집합 기능을 가지는 실버라이트는 점점 더 그 기능을 추가해 나갈 것이다. 현재 1.1 알파 버전에서 사용할 수 있는 컨트롤이 다양하지는 않지만 앞으로 많이 추가될 것이다. 아래는 WPF와 실버라이트의 특징을 비교한 표이다. 아래 표 내용은 미국 라스베가스에서 열린 MIX07에서 발표한 내용의 일부이다.

<표 3>~<표 5>를 보면 정식 1.1 버전이 나올 때쯤이면 상당히 유용한 기능들이 추가될 것으로 예상된다. 위의 기능들 중 한 가지 아쉬운 것은 1.1 버전에서도 DataGrid 기능은 고려되고 있지 않다는 점이다. 일반적인 응용 프로그램을 만드는데 있어 그리드 기능은 상당히 많이 사용된다. 그리드 기능만 있어도 웬만한 게시판 프로그램도 쉽게 만들 수 있을 것이다. WPF에서는 그리드 컨트롤을 써드파티 제품으로 제공하는데 실버라이트에서는 사용자 정의 컨트롤 기능을 지원하므로 다른 업체들이 이러한 그리드 컨트롤을 만들어서 제공할 수 있을 것으로 예상된다.

실버라이트의 발전 과정을 보고 있으면 마치 영화에서나 보았던 꿈에 그리던 미래의 컴퓨팅 환경이 상상이 되곤 한다. 기존 브라우저의 한계를 뛰어 넘는 자유로운 사용자 인터페이스는 새로운 웹 환경을 만들어 나갈 수 있을 것이다.


 

출처명 : 한국마이크로소프트 [2007년 6월호]
 

더 큰 세상으로 가는 문 액티브X 대체기술

 

기획/정리 l 전희용 기자 flytgr@imaso.co.kr

 

마소 독자치고 액티브X 문제와 무관하다고 할 수 있는 사람은 별로 없을 것이다. 그런데, 참 이상한 일은 액티브X 이야기만 나오면 문제의 원인이나 해결책을 이야기하기 보단 목에 핏대부터 세운다. 누군가를 탓하기 위함이다. 하지만 막상 따지고 보면 누구의 잘못이라고 하기는 어려운 일이다. 워낙 오랫동안 쌓아온 일이기 때문이다.
그렇다고 곪을 대로 곪은 상처를 그냥 놓아둘 수도 없는 일. 이번 달 특집에서는 이 상처의 원인에 대해 알아보고, 그 치료방법인 액티브X의 대체 기술들에 대해서도 함께 알아본다. 다들 잘 알다시피 아직 액티브X를 1대1로 대신해 줄 수 있는 기술은 없다. 하지만, 여러 기술들을 이용하여 산적한 문제들을 보완하며 차츰 치료해 나갈 수는 있을 것이다. 깊이 박힌 상처가 하루아침에 낫는 걸 보았는가?

 

1부 | 백조에서 미운오리로 전락한 액티브X 문제와 해결방안 | 정희용

2부 | 발등의 불끄기 공인인증서 대체기술 | 최상훈

3부 | UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발 | 박영록

4부 | 액티브X 뛰어넘는 기능과 호환성 XPCOM 개발전략 | 김민수

5부 | MS가 내놓은 액티브X의 대안 실버라이트 활용법 | 한용희

 

액티브X를 뛰어넘는 기능과 호환성 XPCOM 개발 테크닉

 

액티브X 문제로 때 아닌 진통을 겪고 있는 나라는 놀랍게도 우리나라뿐이다. 미국이나 유럽 대부분의 국가들은 https 프로토콜 하나로 ID만으로 인증하면 그걸로 끝인 탓이다. 보안 능력을 높이기 위해 사용자에게 그 이상의 요구를 하지 않는다. 그들의 보안 의식이 낮은 탓일까? 필자는 그렇게 생각하지 않는다. MS의 조국인 미국에서 조차 선호하지 않고 있는 액티브X의 지나친 사용을 이제는 되돌아보고 바로잡을 때다. 특집 4부에서는 XPCOM을 통해 기존의 액티브X를 어떻게 대체할 수 있는지에 대해 알아본다.

 

김민수 | mskim@transware.co.jp | 일본 웹 애플리케이션 개발회사 한국 지사 개발팀 근무

 

XPCOM, 앞에 두 글자 XP와 뒤에 COM를 보면 Windows XP와 무슨 관련이 있는 기술처럼 보인다. 그도 그럴 것이 COM와 COM+로 대표되는 액티브X를 위시한 마이크로소프트(이하 MS)의 컴포넌트 기술과 비슷한 단어인 Cross Platform Compo nent Object Model의 약자이기 때문이다. 그래서 어느 정도 관련이 있다고도 볼 수 있는 기술이다. 하지만, 결정적으로 MS는 수익을 추구하는 회사란 집단이고 XPCOM을 만든 모질라 재단은 비영리단체라는 것이다. 물론, 수익 추구라는 차이를 내세워 표준인지 아닌지를 가름 할 수는 없다. 하지만 MS의 브라우저 IE는 리눅스용이 없다. 하지만 모질라재단의 파이어폭스는 윈도우는 물론 리눅스와 유닉스, 맥OS, OS/2 등등 현존하는 거의 모든 OS를 지원하고 있다. 즉, 지원하는 플랫폼이 다양하기 때문에 더욱 범용적으로 사용할 수 있고 액티브X를 대체하는 것에 더하여 표준으로 자리 잡기에 충분하다고 얘기할 수 있겠다.

 

이번 특집에서는 기존에 마소를 통해 소개된 적 있는 XPCOM의 소개 기사는 최대한 배제하고, 다양한 플랫폼에 XPCOM을 어떻게 적용하면 좋을 지에 대한 활용 기사 위주로 다룰 것이다. XPCOM에 대해 더 궁금한 독자들은 원고 중에 제시된 링크를 참조하길 바란다.

 

 

SDK 다운로드와 설치하기

 

 

XPCOM으로 개발하려면 SDK를 다운로드 받아 설치해야 한다. 다음의 링크를 통해 필요한 파일을 다운로드 받을 수 있다.

Mozilla Gecko SDK 다운로드

● Branch
- 윈도우즈 환경의 Visual C++ 컴파일러 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-1.7/gecko-sdk-i586-pc-msvc.zip
- 윈도우즈 환경의 Cygwin GCC 컴파일러 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-1.7/gecko-sdk-i686-pc-cygwin.zip
- 리눅스 환경의 GCC 컴파일러 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-1.7/gecko-sdk-i686-pc-linux-gnu.tar.gz
- 리눅스 환경의 GCC 컴파일러 GTK2+XFT 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-1.7/gecko-sdk-i686-pc-linux-gnu-gtk2+xft.tar.gz

● Trunk
- 윈도우즈 환경의 Visual C++ 컴파일러 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-trunk/gecko-sdk-i586-pc-msvc.zip
- 리눅스 환경의 GCC 컴파일러 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-trunk/gecko-sdk-i686-pc-linux-gnu.tar.gz
- 리눅스 환경의 GCC 컴파일러 GTK2+XFT 버전
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-trunk/gecko-sdk-i686-pc-linux-gnu-gtk2+xft.tar.gz

 

C++로 작성하는 XPCOM

 

 

먼저 각각의 과정을 살펴보면 가장 먼저 xxIxxx.idl를 만들고, 그 뒤에 xpidl를 이용하여 xxIxxx.xpt와 xxIxxx.h를 작성한다. 또, xxIxxx.h로부터 xxxxx.h, xxxxx.cpp와 xxxxxModule.cpp를 작성하고 나서 Makefile.in를 작성하고 파이어폭스와 함께 빌드하면 된다.

<리스트 1> xxIxxx.idl

#include "nsISupports.idl"
[scriptable, uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]
interface xxIxxx : nsISupports
{
long add(in long a, in long b);
};

<리스트 1>은 두 개의 숫자를 입력받아 더하는 역할을 하는 xxlxxx.idl 코드다. 이제 다음과 같이 xpidl를 이용하여 xxIxxx.xpt 와 xxIxxx.h를 작성해 보자.

xpidl -m typelib -I c:xxx_gecko_sdk xxIxxx.idl
xpidl -m header -I c:xxx_gecko_sdk xxIxxx.idl

다음으로 해야 할 일은 xxxxx.ccp를 작성하기 위해 xxIxxx.h에 있는 /* Header file */ 부터 /* Implementation file */ 의 앞까지를 xxxxx.h에 복사한 뒤에 xxxxx()를 virtual xxxxx()로 바꾸는 것이다.

<리스트 2> xxxxx.h 작성

#ifndef _XX_XXX_H_
#define _XX_XXX_H_

#include "xxIxxx.h"

#define XX_XXX_CONTRACTID "@xxx.xxx.kr/xx_ext/xxx;1"
#define XX_XXX_CLASSNAME "This is Sample"
#define XX_XXX_CID {0x00000000, 0x0000, 0x0000,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}

// 위의 내용을 앞에 추가한다. XX_XXX_CID 는 xxIxxx.h 의 XXXXX_IID 를 복사한다.

#endif //_XX_XXX_H_

xxxxx.cpp는 xxIxxx.h에 있는 /* Implementation file */부터 /* End of implementation class template. */ 까지를 복사하여 만들면 된다.

<리스트 3> xxxxx.cpp 작성

#include "xxxxx.h"
// 위의 헤더를 추가

이번에는 모듈 등록을 위해 <리스트 4>와 같이 xxxxxModule. cpp 파일을 만든다.

<리스트 4> xxxxxModule.cpp

#include "nsIGenericFactory.h"
#include "xxxxx.h"

NS_GENERIC_FACTORY_CONSTRUCTOR(xxxxx)

static nsModuleComponentInfo components[] =
{
{
XX_XXX_CLASSNAME,
XX_XXX_CID,
XX_XXX_CONTRACTID,
xxxxxConstructor,
},
};

NS_IMPL_NSGETMODULE(xxxxxModule, components)

 

 

C++ 의 XPCOM on Linux

 

 

이번에는 리눅스에 C++ XPCOM을 적용하는 방법에 대해 알아볼 것이다. 여기에서는 Debian GNU/Linux를 기준으로 하여 진행한다. 리눅스에서는 .so 형식의 셰어드 라이브러리로 만들어야 한다.

가장 먼저 다음과 같은 방법으로 작업용 디렉토리를 만든다.

% mkdir -p xpcom-sample/{content/xpcom-sample,components}
% cd xpcom-sample

코드를 작성하기 전에 일단 XPCOM을 인스톨 하는 확장 기능을 만들어 보자.

<리스트 5> install.rdf

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>xpcom-sample@imaso.co.kr</em:id>
<em:name>XPCOM sample</em:name>
<em:version>0.1</em:version>
<em:description>XPCOM sample</em:description>
<em:creator>Min-su Kim</em:creator>

<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>2.0.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

파이어폭스의 사용자 유저 인터페이스의 환경을 저장하는 chrome 파일을 확인한다.

<리스트 6> chrome.manifest

content xpcom_sample content/
overlay chrome://browser/content/browser.xul chrome://xpcom_sample/content/overlay.xul

인스톨러 작성 스크립트도 만든다.

<리스트 7> dist.sh

#!/bin/sh

cd `dirname $0`

#basename=`basename $PWD`
basename=xpcom-sample
version=`grep '<em:version>' install.rdf | sed -e 's,</?em:version>,,g'`
version=`echo $version | sed -e 's/[[:space:]]//g'`

xpi=$basename-$version.xpi

if [ -f components/Makefile ]; then
(cd components && make) || exit 1
component_shared="components/myCalc.so"

component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"
fi
xpi_contents="content $components chrome.manifest install.rdf"

rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x */.svn/* || exit 1

<리스트 7>처럼 dist.sh가 만들어졌으면 다음과 같이 입력하여 .xpi를 작성한다.

% ./dist.sh

현재 디렉토리에 xpcom-sample-0.1.xpi을 인스톨하기 위해 다음과 같이 입력한다.

% iceweasel xpcom-sample-0.1.xpi

파이어폭스에서 [툴] - [애드 온(add-on)] 메뉴를 선택하여 ‘XPCOM sample’이 인스톨 되어 있는지 확인한다.
자 이제 XPCOM을 사용할 모든 준비가 끝났으니 실제 코드들을 만들어보자.

 

IDL의 작성 편집

 

가장 먼저 할 일은 components 디렉토리에 myICalc.idl를 작성하는 것이다. components 디렉토리 아래에 작성하여 파이어폭스가 자동으로 XPCOM를 검출해 읽어 들일 수 있도록 해 준다. 그렇게 하지 않으면 수동으로 등록하지 않으면 안 된다.

IDL 안의 uuid를 uuidgen(참고링크3)로 생성한다.

% uuidgen
c95498ae-16f5-4b46-8713-2cf79e30d4ef

<리스트 8> compornts/myICalc.idl

#include "nsISupports.idl"
[scriptable, uuid(c95498ae-16f5-4b46-8713-2cf79e30d4ef)]
interface myICalc : nsISupports
{
long add(in long a, in long b);
};

 

.xpt와 .h 생성하기와 편집하기

 

IDL이 다 만들어졌다면 이번에는 만들어 놓은 IDL 로부터 .xpt와 .h를 생성할 차례다. xpidl를 사용하여 .xpi와 .h를 만든다. 이 두 파일은 .idl 를 수정할 때마다 만들어야 하므로 Makefile로 만들어 두는 것이 좋다.

여기에서는 XULRunner를 사용하고 있는데 데비안 이외의 리눅스 환경에서는 GECKO_PATH나 GECKO_XXX_PATH를 변경 할 필요가 있을 것이다.

<리스트 9> components/Makefile

GECKO_PATH = /usr/lib/xulrunner
GECKO_SDK_PATH = $(GECKO_PATH)/sdk

GECKO_IDL_PATH = $(GECKO_SDK_PATH)/idl

XPIDL = $(GECKO_PATH)/xpidl

IDL = myICalc.idl
XPT = myICalc.xpt
IHEADER = myICalc.h

all: $(XPT) $(IHEADER)

$(XPT): $(IDL)
$(XPIDL) -m typelib -I$(GECKO_IDL_PATH) $(IDL)

$(IHEADER): $(IDL)
$(XPIDL) -m header -I$(GECKO_IDL_PATH) $(IDL)

clean:
rm -f $(XPT) $(IHEADER)

dist.sh를 실행해 .xpi 를 생성한 후에 다시 인스톨한다.

% ./dist.sh
/usr/lib/xulrunner/xpidl -m typelib -I/usr/lib/xulrunner/sdk/idl myICalc.idl
/usr/lib/xulrunner/xpidl -m header -I/usr/lib/xulrunner/sdk/idl myICalc.idl
% iceweasel xpcom-sample-0.1.xpi

.xpt가 인식되고 있는지 확인하려면 다음과 같이 입력해 보자.

% grep xpcom-sample /.mozilla/firefox/*/xpti.dat

다음과 같은 결과가 출력되면 .xpt가 정상적으로 인식된 것이다.

4,.../extentions/xpcom-sample@imaso.co.kr/components

 

XPCOM의 설치하기

 

우선은 myCalc.h를 작성해야 하는데 여기에서도 UUID가 필요하다. 다음과 같이 입력하여 사전에 UUID를 만들어 둔다.

% uuidgen
8931dfd3-edf3-4b7d-bd44-1da72064f0dc

이렇게 만들어진 uuid를 16진수로 나누어 코드에 적용하기 위해 다음과 같이 포맷을 변환해 두어야 한다.

8931dfd3-edf3-4b7d-bd44-1da72064f0dc

8931dfd3 edf3 4b7d bd 44 1d a7 20 64 f0 dc

0x8931dfd3 0xedf3 0x4b7d 0xbd 0x44 0x1d 0xa7 0x20 0x64 0xf0 0xdc

{0x8931dfd3, 0xedf3, 0x4b7d, {0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}

이것을 요즘 유행하는 스크립트 언어인 루비를 이용해서 만들어 보자.

<리스트 10> split-uuid.rb

#!/usr/bin/env ruby

ARGV.each do |uuid|
uuid_components = uuid.split(/-/)
first_components = uuid_components.slice!(0, 3)
second_components = []
uuid_components.each do |uuid_component|
second_components.concat(uuid_component.scan(/../))
end
first_components = first_components.collect do |component|
"0x#{component}"
end.join(", ")
second_components = second_components.collect do |component|
"0x#{component}"
end.join(", ")
puts "{#{first_components}, {#{second_components}}}"
end

혹은 이렇게 한다.

<리스트 11> split-uuid2.rb

#!/usr/bin/env ruby

ARGV.each do |uuid|
uuid_components = uuid.split(/-/)
first_components = uuid_components.slice!(0, 3)
second_components = uuid_components.inject([]) do |result, component|
result + component.scan(/../)
end
first, second = [first_components, second_components].collect do |components|
components.collect do |component|
"0x#{component}"
end.join(", ")
end
puts "{#{first}, {#{second}}}"
end

<리스트 10>이나 <리스트 11>과 같이 하면 다음과 같은 두 형식의 UUID가 만들어진다.

8931dfd3-edf3-4b7d-bd44-1da72064f0dc
{0x8931dfd3, 0xedf3, 0x4b7d, {0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}

헤더 파일은 components/myICalc.h에 있는 것을 카피하여 사용한다.

<리스트 12> components/myCalc.h

#ifndef __MYCALC_H__
#define __MYCALC_H__

#include "myICalc.h"

#define MY_CALC_CONTRACT_ID "@imaso.co.kr/xpcom-sample/Calc;1"
#define MY_CALC_CLASS_NAME "Calculator"
#define MY_CALC_CID_STR "8931dfd3-edf3-4b7d-bd44-1da72064f0dc"
#define MY_CALC_CID
{0x8931dfd3, 0xedf3, 0x4b7d,
{0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}

class myCalc : public myICalc
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MYICALC

myCalc();

private:
myCalc();

protected:
/* additional members */
};

#endif

cpp도 components/myICalc.cpp에 있으므로 그것을 복사하고 add를 추가한다.

<리스트 13> components/myCalc.cpp

#include "mozilla-config.h"
#include "myCalc.h"

NS_IMPL_ISUPPORTS1(myCalc, myICalc)

myCalc::myCalc()
{
/* member initializers and constructor code */
}

myCalc::myCalc()
{
/* destructor code */
}

/* long add (in long a, in long b); */
NS_IMETHODIMP myCalc::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)
{
*_retval = a + b;
return NS_OK;
}

#include "mozilla-config.h"
#include "myCalc.h"

NS_IMPL_ISUPPORTS1(myCalc, myICalc)

myCalc::myCalc()
{
/* member initializers and constructor code */
}

myCalc::myCalc()
{
/* destructor code */
}

/* long add (in long a, in long b); */
NS_IMETHODIMP myCalc::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)
{
*_retval = a + b;
return NS_OK;
}

components/Makefile를 수정하여 컴파일 할 수 있도록 한다.

<리스트 14> components/Makefile

CXX = c++
CXXFLAGS = -g -Wall -fno-rtti -fno-exceptions -shared

GECKO_PATH = /usr/lib/xulrunner
GECKO_SDK_PATH = $(GECKO_PATH)/sdk

GECKO_IDL_PATH = $(GECKO_SDK_PATH)/idl
GECKO_INCLUDE_PATH = $(GECKO_SDK_PATH)/include
GECKO_LIB_PATH = $(GECKO_SDK_PATH)/lib

XPIDL = $(GECKO_PATH)/xpidl

GECKO_INCLUDES = -I$(GECKO_INCLUDE_PATH)
GECKO_CFLAGS = -DXPCOM_GLUE $(GECKO_INCLUDES)

GECKO_LDFLAGS = -L$(GECKO_LIB_PATH)
GECKO_LIBS = -lxpcomglue
-lnspr4
-lplds4

OBJS = myCalc.o

IDL = myICalc.idl
XPT = myICalc.xpt
IHEADER = myICalc.h
SHARED = myCalc.so

all: $(XPT) $(IHEADER) $(SHARED)

$(XPT): $(IDL)
$(XPIDL) -m typelib -I$(GECKO_IDL_PATH) $(IDL)

$(IHEADER): $(IDL)
$(XPIDL) -m header -I$(GECKO_IDL_PATH) $(IDL)

$(SHARED): $(IHEADER) $(OBJS)
$(CXX) $(CXXFLAGS) $(GECKO_LDFLAGS) -o $(SHARED) $(OBJS) $(GECKO_LIBS)

clean:
rm -f $(XPT) $(IHEADER) $(OBJS) $(SHARED)

.cpp.o:
$(CXX) $(CXXFLAGS) $(GECKO_CFLAGS) -c $<

dist.sh를 실행해 컴파일 할 때 모질라의 헤더 파일에 warning 메시지가 표시되지만 큰 문제는 없다.

 

컴파일 시 warning 메시지들

 

% ./dist.sh
c++ -g -Wall -fno-rtti -fno-exceptions -shared -DXPCOM_GLUE -I/usr/lib/xulrunner/sdk/include -c myCalc.cpp
/usr/lib/xulrunner/sdk/include/nsISupportsBase.h:80: warning:
‘class nsISupports
' has virtual functions but non-virtual destructor
/usr/lib/xulrunner/sdk/include/nsIProgrammingLanguage.h:32: warning:
‘class nsIProgrammingLanguage
' has virtual functions but non-virtual destructor
/usr/lib/xulrunner/sdk/include/nsIClassInfo.h:33: warning:
‘class nsIClassInfo
' has virtual functions but non-virtual destructor
myICalc.h:25: warning:
‘class myICalc
' has virtual functions but non-virtual destructor
c++ -g -Wall -fno-rtti -fno-exceptions -shared -L/usr/lib/ xulrunner/sdk/lib -o myCalc.so myCalc.o -lxpcomglue -lnspr4 -lplds4

이것으로 components/myCalc.so를 만들어 사용 할 수 있다. 하지만, 이것만으로는 아직 부족하다.

 

XPCOM 등록하기

 

공유 라이브러리가 읽혔을 때에 XPCOM을 등록하는 기능이 필요하다면 그 기능은 <리스트 15>와 같이 components/my CalcModule.cpp로 구현하면 된다.

<리스트 15> components/myCalcModule.cpp

#include "nsIGenericFactory.h"
#include "myCalc.h"

NS_GENERIC_FACTORY_CONSTRUCTOR(myCalc)

static nsModuleComponentInfo components[] =
{
{
MY_CALC_CLASS_NAME,
MY_CALC_CID,
MY_CALC_CONTRACT_ID,
myCalcConstructor,
}
};

NS_IMPL_NSGETMODULE("myCalcModule", components)

또한 components/Makefile의 OBJS에도 추가한다.

<리스트 16> components/Makefile

...
OBJS = myCalc.o myCalcModule.o
...

예제에서는 myCalc 하나만을 등록하고 있지만 복수의 XPCOM이 하나의 공유 라이브러리에 들어갈 수도 있다. 프로그램 패키지를 묶어서 인스톨하기 위해 다음과 같이 스크립트를 입력한다.

% ./dist.sh
...
% iceweasel xpcom-sample-0.1.xpi

myCalc가 등록되었는지 확인하려면 다음과 같이 입력한다.

% grep myCalc /.mozilla/firefox/*/compreg.dat

이렇게 입력한 결과가 다음과 같이 나오면 제대로 등록된 것이다.

abs:/.../xpcom-sample@imaso.co.kr/components/myCalc. so,1173322260000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs: /.../myCalc.so

 

테스트용 인터페이스

 

대화형으로 xul을 사용하여 팝업의 인터페이스를 만들어 자바스크립트의 식을 테스트하는 인터페이스를 만들어 보자.

<리스트 17> content/overlay.xul

<?xml version="1.0"?>
<overlay
id="test-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/ there.is.only.xul">

<menubar id="main-menubar">
<menu label="XPCOM sample">
<menupopup>
<menuitem label="Call sample XPCOM"
oncommand=”
(function () {
var obj;
try {
const cid = '@imaso.co.kr/xpcom-sample/Calc;1';
obj = Components.classes[cid].createInstance();
obj = obj.QueryInterface(Components.interfaces.myICalc);
} catch (err) {
alert(err);
return;
}
alert('3 + 4 = ' + obj.add(3, 4));
})();
"/>
</menupopup>
</menu>
</menubar>
</overlay>

역시 .xpi 를 다시 인스톨 한다.

% ./dist.sh
% iceweasel xpcom-sample-0.1.xpi

[XPCOM sample] 메뉴에서 [Call sample XPCOM]를 실현한 뒤에 ‘3 + 4 = 7’라는 메시지가 표시되면 성공이다.

 

 

C++ 의 XPCOM on Mac OS X

 

 

이번에는 Mac OS X에서 실행되는 C++ XPCOM을 만들어보자.

Mac OS X에서는 GCC 대신 Xcode를 사용하여 컴파일 한다. Mac에서 라이브러리는 dylib 형식으로 만들기 때문에 리눅스용 Makefile을 사용할 수 없을 뿐 아니라 dist.sh도 변경해야 한다.

Xcode의 프로젝트는 components/myCalc.xcodeproj/ 에 위치한다.

가장 먼저 <리스트 18>과 같이 dist.sh를 수정해 보자.

<리스트 18> Mac OS X 환경에 맞게 인스톨 패스와 파일 확장자를 수정한 dist.sh

#!/bin/sh

cd dirname $0

if [ -x "which gnused" ]; then
SED=gnused
else
SED=sed
fi

#basename=basename $PWD
basename=xpcom-sample
version=grep '<em:version>' install.rdf | $SED -e 's,</?em:version>,,g'
version=echo $version | $SED -e 's/[[:space:]]//g'

xpi=$basename-$version.xpi

case uname in
Linux)
(cd components && make) || exit 1
component_shared="components/myCalc.so"
;;
Darwin)
build_type=Release
xcodebuild_args="-project myCalc.xcodeproj -configuration $build_type"
(cd components && xcodebuild $xcodebuild_args) || exit 1
component_shared="components/libmyCalc.dylib"
cp components/build/$build_type/libmyCalc.dylib $component_shared
;;
*)
echo "Unknown environment"
exit 1
;;
esac

component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"

xpi_contents="content $components chrome.manifest install.rdf"

rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x */.svn/* || exit 1

Mac OS X의 gecko-sdk에는 xpidl이 들어있는데, 여기에는 요즘은 오래된 버전의 glib와 libIDL이 포함되어 있다. 이 정도의 버전은 최근의 MacPorts로는 가져오기가 어렵기 때문에 Linux에서 생성한 .xpt와 .h를 불러와서 사용해야 한다.

다음과 같이 dist.sh를 실행하여 .xpi를 작성한다.

% ./dist.sh

만들어진 xpcom-sample-0.1.xpi를 파이어폭스에 마우스로 드래그앤드롭하면 인스톨 되고 메뉴에 [XPCOM sample]이 표시된다. [Call sample XPCOM]를 선택하여 ‘3 + 4 = 7’라는 메시지가 표시되면 성공이다.

커맨드 라인으로부터 확인하려면 리눅스에서와 마찬가지로 다음과 같이 입력하면 된다.

% grep myICalc /Library/Application Support/Firefox/Profiles/ */xpti.dat

 

 

Xcode 프로젝트 작성하기

 

 

다음은 Xcode 프로젝트를 작성하는 과정을 간략하게 설명한 것이다. 지면 관계상 각 단계들을 일일이 설명할 수 없는 탓이다. 어려운 과정이 아니므로 다음 과정들을 참고하여 Xcode 프로젝트를 만들어보자.

1. 파일 → 신규 프로젝트

2. 프로젝트
· 프로젝트명: myCalc
· 디렉토리: .../xpcom-sample/components/

3. 왼쪽의 myCalc 라는 곳에서 오른쪽 클릭
· 추가 → 신규 타깃
· BSD/Dynamic Library
- 타깃 명: myCalc

4. [타깃 myCalc의 정보] 대화상자가 나타나면 지운다.

5. 왼쪽의 myCalc라는 곳에서 오른쪽 클릭
· 추가 → 기존의 파일
· myCalc.cpp, myCalc.h myCalcModule.cpp, myCalc.h를 선택, 정리하여 추가
· prompt가 나오면 디폴트 추가(타깃으로 추가한 조금 전 만든 myCalc에 체크가 있는 것을 확인)

6. 왼쪽의 myCalc라는 곳에서 더블 클릭
· [프로젝트 myCalc의 정보] 대화상자가 표시된다
· [일반] 탭 → [타깃 SDK를 사용한 크로스 개발]: [Mac OS X 10.4 (Universal)]
· [빌드] 탭 → [구성]: [모든 구성]
· [아키텍처] → 아래쪽에 있는 [편집] 버튼: [PowerPC]와 [Intel]에 체크
· [헤더 검색 패스] → 아래쪽에 있는 [편집]버튼: 아래에 있는 [+] 버튼을 누르고 항목을 늘려 gecko-sdk/include에 패스를 정한다
- 상대 패스로 하는 경우에는 소스 중에서 components/ 디렉토리로부터 지정
- 샘플 소스 중에서는 톱 디렉토리(xpcom-sample)와 같은 디렉토리에 gecko-sdk로 있다
· [라이브러리 검색 패스] → 아래쪽에 있는 [편집] 버튼: 아래에 있는 [+] 버튼을 누르고 항목을 늘려 Firefox.app/Contents/Mac OS에 패스워드를 정한다
- 샘플 소스 중에서는 /Applications/ 이하에 Firefox.app 하지만 인스톨 되어 있다
· [다른 링커 옵션] → 아래쪽에 있는 [편집] 버튼: 아래에 있는 [+] 버튼을 5회 누르고 항목을 늘려, 각각 [-lxpcom_core]와 [-lxpcom], [-lnspr4], [-lplds4], [-lplc4] 추가

7. 메뉴로부터 [빌드] → [모든 타깃을 클리닝]

8. 메뉴로부터 [빌드] → [빌드]

9. 메인 윈도우의 왼쪽의 [에러와 경고]를 보고 경고·에러가 나와 있지 않은 것을 확인

 

비주얼 스튜디오의 솔루션 작성 방법

 

다음은 비주얼 스튜디오에서 솔루션을 작성하는 방법을 간단히 정리한 것이다. 만약 비주얼 스튜디오의 사용법이 익숙지 않다면 다음 내용을 참조하여 솔루션을 작성해 보자.

1. 파일 → 신규 작성 → 프로젝트

2. Visual C++ → 프로젝트
· 프로젝트명: myCalc
· 장소: .../xpcom-sample/components/
· 솔루션의 디렉토리를 작성: 체크 하지 않음

3. 완료

4. 왼쪽의 myCalc → 원시 파일로 오른쪽 클릭
· 추가 → 기존의 항목 → 상의 폴더에 말해 myCalc.cpp와 myCalcModule.cpp 선택 → 추가

5. 왼쪽의 myCalc → 헤더 파일로 오른쪽 클릭
· 추가 → 기존의 항목 → 상위 폴더에서 myCalc.h와 myICalc.h를 선택 → 추가

6. 프로젝트 → myCalc 의 프롭퍼티
· 왼쪽 위의 드롭다운 리스트의 구성: 모든 구성
· 구성 프로퍼티 → C/C++ → 전반 → 추가의 인클루드 디렉토리
- ......gecko-sdkinclude(xpcom-sample와 같은 레벨의 gecko-sdk)
· 구성 프롭퍼티 → 링커 → 전반 → 추가의 라이브러리 디렉토리
- ......gecko-sdklib(xpcom-sample와 같은 레벨에 gecko-sdk)
· 구성 프롭퍼티 → 링커 → 입력 → 추가의 의존 파일
- xpcomglue_s.lib xpcom.lib nspr4.lib
- Rlease로 구성하여 libcmt.lib 추가
- 구성을 모든 구성에 되돌린다
· 구성 프롭퍼티 → 링커 → 입력 → 특정의 라이브러리의 무시
- MSVCRT
· 구성 프롭퍼티 → 링커 → 마니페스트 → 마니페스트의 생성
- 아니오

 

다음과 같이 나오면 .xpt의 인스톨은 성공한 것이다.

 

142,myICalc.xpt,6,134,1173341340000
1294,myICalc,{c95498ae-16f5-4b46-8713-2cf79e30d4ef},142,-1,1

이번에는 XPCOM이 정상적으로 인스톨 되었는지 확인하기 위해 다음과 같이 입력해 본다.

% grep myCalc /Library/Application Support/Firefox/Profiles/*/ compreg.dat

입력한 내용의 성공 메시지는 다음과 같다.

abs:/.../xpcom-sample@imaso.co.kr/components/libmyCalc. dylib,1173345060000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs:/.../ libmyCalc.dylib

 

 

C++ 의 XPCOM on 윈도우

 

 

윈도우에서의 XPCOM 확장자(extension)는 .dll이다. 또, 비주얼 스튜디오는 Makefile이 아니라, 솔루션 파일을 사용해 컴파일 한다. 이런 특징에 유연하게 대처하려면 dist.sh를 변경해야 한다.

비주얼 스튜디오 8의 솔루션 파일은 components/myCalc/my Calc.sln에 배치하기로 한다. 또, devenv.exe(비주얼 스튜디오 8의 커맨드 명)에 패스워드가 걸리지 않은 경우는 C:Program Files\Microsoft Visual Studio 8\Common7IDE\devenv.exe 에 있다고 가정한다.

<리스트 19> 윈도우 환경에 맞게 인스톨 패스와 파일 확장자를 수정한 dist.sh

#!/bin/sh
cd dirname $0
if [ -x "which gnused 2>&1 /dev/null" ]; then
SED=gnused
else
SED=sed
fi
#basename=basename $PWD
basename=xpcom-sample
version=grep '<em:version>' install.rdf | $SED -e 's,</?em:version>,,g'
version=echo $version | $SED -e 's/[[:space:]]//g'
xpi=$basename-$version.xpi
case uname in
Linux)
(cd components && make) || exit 1
component_shared="components/myCalc.so"
;;
Darwin)
build_type=Release
xcodebuild_args="-project myCalc.xcodeproj -configuration $build_type"
(cd components && xcodebuild $xcodebuild_args) || exit 1
component_shared="components/libmyCalc.dylib"
cp components/build/$build_type/libmyCalc.dylib $component_shared
;;
CYGWIN*)
build_type=Release
if which devenv > /dev/null; then
DEVENV="devenv"
else
DEVENV="/cygdrive/c/Program Files/Microsoft Visual Studio 8/Common7/IDE/devenv.exe"
fi
"$DEVENV" /Build $build_type components/myCalc/myCalc.sln || exit 1
component_shared="components/myCalc.dll"
cp components/myCalc/$build_type/myCalc.dll $component_shared
;;
*)
echo "Unknown environment"
exit 1
;;
esac

component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"

xpi_contents="content $components chrome.manifest install.rdf"

rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x */.svn/* || exit 1

 

.xpt 와 .h 의 생성

 

윈도우용의 gecko-sdk에 들어 있는 xpidl은 오래된 버전의 glib와 libIDL이 컴파일 되어 있다. 이것은 다음과 같이 하면 확인할 수 있다.

% objdump -p ../gecko-sdk/bin/xpidl.exe | grep -i dll
DllCharacteristics 00000000
vma: Hint Time Forward DLL First
DLL Name: libIDL-0.6.dll
DLL Name: glib-1.2.dll
DLL Name: MSVCRT.dll

xpidl의 옵션은 리눅스와 같아서 생략한다.

 

인스톨 편집

 

다른 OS에서와 마찬가지로 다음과 같이 dist.sh를 실행해하여 .xpi를 작성한다.

% ./dist.sh

인스톨 하려면 다른 플랫폼과 똑같이 xpcom-sample-0.1.xpi를 파이어폭스에 드래그앤드롭하면 인스톨 된다. 메뉴에 [XP COM sample]이 표시되면 [Call sample XPCOM]를 실행시켜 ‘3 + 4 = 7’라는 메시지가 표시되는지 확인한다.

인스톨 여부를 커맨드 라인에서 확인하려면 다음과 같이 입력한다.

% grep myICalc /cygdrive/c/Documents and Settings/$USER/ Application Data/Mozilla/Firefox/Profiles/*/xpti.dat

다음과 같은 결과가 표시되면 .xpt의 인스톨은 성공이다.

4,myICalc.xpt,3,134,1173668700000
587,myICalc,{c95498ae-16f5-4b46-8713-2cf79e30d4ef},4,-1,1

마지막으로 XPCOM이 인스톨 되었는지 확인하기 위해 다음과 같이 입력하면 된다.

% grep myCalc /cygdrive/c/Documents and Settings/$USER /Application Data/Mozilla/Firefox/Profiles/*/compreg.dat

XPCOM 인스톨 확인 메시지는 다음과 같다.

abs:C:\...\xpcom-sample@imaso.co.kr\components\ myCalc.dll,1173763800000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs:C:\ ...\myCalc.dll

지금까지 각 운영체제별 XPCOM 개발 예제에 대해 간단히 알아보았다. 지면 한계상 의도했던 내용의 절반 정도 밖에는 소개하지 못하여 아쉬움이 남는다. 하지만 우리에겐 인터넷과 커뮤니티가 있다. 아직 한국의 모질라 개발자 커뮤니티 등에는 다양한 자료와 질문, 답변들이 준비되어 있다. 특집 4부의 내용을 기반으로 커뮤니티의 자료들을 참고하면 XPCOM에 대해 좀 더 다양한 지식들을 얻을 수 있을 것이다.

 

 

출처명 : 한국마이크로소프트 [2007년 6월호]
 

더 큰 세상으로 가는 문 액티브X 대체기술

 

기획/정리 l 전희용 기자 flytgr@imaso.co.kr

 

마소 독자치고 액티브X 문제와 무관하다고 할 수 있는 사람은 별로 없을 것이다. 그런데, 참 이상한 일은 액티브X 이야기만 나오면 문제의 원인이나 해결책을 이야기하기 보단 목에 핏대부터 세운다. 누군가를 탓하기 위함이다. 하지만 막상 따지고 보면 누구의 잘못이라고 하기는 어려운 일이다. 워낙 오랫동안 쌓아온 일이기 때문이다.
그렇다고 곪을 대로 곪은 상처를 그냥 놓아둘 수도 없는 일. 이번 달 특집에서는 이 상처의 원인에 대해 알아보고, 그 치료방법인 액티브X의 대체 기술들에 대해서도 함께 알아본다. 다들 잘 알다시피 아직 액티브X를 1대1로 대신해 줄 수 있는 기술은 없다. 하지만, 여러 기술들을 이용하여 산적한 문제들을 보완하며 차츰 치료해 나갈 수는 있을 것이다. 깊이 박힌 상처가 하루아침에 낫는 걸 보았는가?

 

1부 | 백조에서 미운오리로 전락한 액티브X 문제와 해결방안 | 정희용

2부 | 발등의 불끄기 공인인증서 대체기술 | 최상훈

3부 | UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발 | 박영록

4부 | 액티브X 뛰어넘는 기능과 호환성 XPCOM 개발전략 | 김민수

5부 | MS가 내놓은 액티브X의 대안 실버라이트 활용법 | 한용희

 

UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발

 

액티브X를 사용하는 가장 큰 이유 두 가지는 클라이언트 자원을 이용할 수 있다는 점과 윈도우의 UI 컴포넌트를 쉽게 사용할 수 있다는 점이다. Ajax는 이 두 가지 용도를 모두 만족시킬 수는 없지만 고급 UI를 필요로 하는 애플리케이션까지 Ajax로 만들 수 있을 정도로 강력한 UI 기능을 지원한다. 특집 3부에서는 이점에 포커싱하여 Ajax로 액티브X를 대체하는 방법들에 대해 알아본다.

 

박영록 | poci@ncsoft.net | 오픈마루 개발자

 

먼저 액티브X가 할 수 있는 일에 대해서 알아보자. 크게 두 가지로 분류할 수 있을 것 같다. 하나는 클라이언트의 자원을 이용하는 일이다. 웹 브라우저의 보안 모델에서는 클라이언트의 자원 중 일부분만 접근할 수 있는데 액티브X를 사용하면 클라이언트의 거의 모든 자원을 이용할 수 있다. 인터넷 뱅킹을 할 때 뜨는 키보드 보안 모듈은 하드웨어 제어를 통해 키보드의 입력을 다른 프로그램이 해킹하지 않는지 감시하는 것이다. 바이러스 검사 프로그램 같은 건 클라이언트의 파일 시스템에 접근할 수 있기 때문에 가능한 것이고 자신의 PC를 다른 사설 네트워크(주로 회사 네트워크)에 소속된 것처럼 만들어주는 VPN(가상 사설 네트워크) 프로그램도 클라이언트의 네트워크 자원을 이용할 수 있기 때문에 가능한 것이다. 물론 게임도 가능하다. 이처럼 클라이언트의 자원을 마음대로 활용할 수 있기 때문에 강력한 도구가 되기도 하지만 스파이웨어 같은 도구로 악용되기도 한다.

또 다른 하나는 윈도우의 UI 컴포넌트들을 쉽게 활용할 수 있다는 것이다. 기본적인 컴포넌트 외에는 모두 직접 만들어야 하는 HTML과는 달리 윈도우의 UI 컴포넌트는 종류도 많고 완성도가 높은데다 GUI 생성 툴도 좋기 때문에 기능성이 높은 UI를 쉽게 만들 수 있다. 그래서 고객이 제한된 SI(시스템 통합) 프로젝트에서는 복잡한 요구사항을 처리하기 위해 액티브X를 선택하는 경우가 많다. 간혹 더 화려하고 막강한 UI를 위해서 액티브X를 쓴다고 하기도 하는데 실상 HTML과 CSS, 자바스크립트로도 고수준 UI를 만드는 일이 그리 어려운 일은 아니다. 그보다 이미 준비되고 검증된 UI 컴포넌트가 많고 겉보기 UI만 만들 수 있는 HTML 위지윅 도구에 비해 동작까지 세밀하게 조정할 수 있는 비주얼 스튜디오가 더 편리하다는 점이 중요하게 작용하는 것 같다.

그럼 Ajax가 할 수 있는 일은 무엇일까. Ajax는 원래는 웹에서 비동기 통신을 하는 기술을 일컫는 말이었다. 하지만 요즘은 의미가 확장되어 DHTML, CSS, 자바스크립트를 포괄하는 개념으로 이야기되기도 한다. 여기서도 이런 넓은 의미의 개념을 Ajax에 적용하는 것이 적절할 듯하다. 이런 측면에서 본다면 Ajax가 대체할 수 있는 것은 앞의 두 가지 중 후자다. Ajax 역시 웹 브라우저 보안 모델을 넘어서진 못하기 때문에 전자의 문제는 전혀 해결할 수 없다. 그런 면에서 Ajax는 액티브X의 완전한 대안은 아닌 셈이다. 하지만 후자의 경우는 상당히 많은 부분을 대체할 수 있다. 요즘에는 워드프로세서나 스프레드시트처럼 고급 UI를 필요로 하는 애플리케이션도 액티브X를 전혀 쓰지 않고 만들어내는 경우도 볼 수 있을 정도다.


<화면 1> 위키 기반 웹노트 서비스 : 스프링노트

특집 3부에서는 Ajax로 액티브X를 대체하는 몇 가지 사례들에 대해 알아볼 것이다. 가급적 추상적인 이야기들보다는 코드로 이야기하면서 자바스크립트와 HTML/CSS로 UI를 만들어 나가는 것이 생각보다 쉽고 재미있다는 사실을 보여주고 싶다.

 

 

HTML WYSIWYG 에디터 만들기

 

 

과거 단순 텍스트만 저장하던 게시판이 점점 진화하여 다양한 스타일을 표현하려는 욕구가 강해지면서 카페나 블로그 등에도 액티브X나 자바 애플릿으로 만든 에디터가 많이 채용되었다. 그런데 요즘에는 액티브X 에디터들이 순수 HTML/자바스크립트 에디터가 점차 늘어나는 추세다. 최신 웹 브라우저들에 위지윅(WYSIWYG) 에디터가 탑재되면서 액티브X 없이 구현할 수 있게 된 것이다. 웹 브라우저에 내장된 위지윅 에디터를 사용하면 게시판 등에 위지윅 에디터를 붙이는 일은 별로 어렵지 않다. 이미 오픈소스로 완성도 높은 에디터도 많이 나와 있지만 여기서는 직접 만들어보자. 파이어폭스와 IE의 API가 조금씩 다르기 때문에 그 차이점도 조금 살펴볼 것이다.

 

HTML 편집 모드

 

위지윅 에디터를 이용하는 방법은 두 가지다. 하나는 자바스크립트에서 document.designMode에 ‘on’ 값을 주는 것이다. 그러면 페이지 전체가 에디팅 할 수 있는 모드로 바뀌게 된다. 이 방법은 파이어폭스와 IE 모두 동작한다. <리스트 1>을 보자.

<리스트 1> Hello World

<html>
<head>
<script type="text/javascript">
document.designMode = 'on'
</script>
</head>
<body>
<h2>Hello</h2>
<p>World</p>
</body>
</html>

<리스트 1>을 브라우저로 열면 <화면 2>와 같이 보인다.


<화면 2> <리스트1>의 실행 결과

겉보기론 별 다를 바 없어 보이지만 이 페이지는 브라우저상에서 편집이 가능하다. 만약 e와 l 사이에 커서가 있는 상태에서 a를 입력하면 Heallo가 보일 것이다. 물론 스타일은 주변 스타일을 그대로 유지한다. 화살표 키로 이동하는 것도 일반 에디터와 비슷하고 글자를 입력하거나 지우는 것도 비슷하다. 웹 브라우저 자체에서 키 입력을 받아서 HTML 문서의 DOM 객체를 수정하는 것이다. 그래서 DOM Inspector 등으로 보면 <h2> 엘리먼트의 내용이 Heallo로 바뀌는 것을 볼 수 있다.

IE에는 designMode와는 별개로 또 contentEditable이라는 속성이 있다. designMode가 HTML 문서 전체를 편집할 수 있도록 하는데 반해 contentEditable 속성은 document 객체의 속성이 아니라 엘리먼트의 속성으로 HTML 문서의 일부분만 편집할 수 있도록 할 수 있다. div나 span, a 등의 엘리먼트에 적용할 수 있다. 그래서 웹 에디터를 만들기는 파이어폭스보다 IE가 조금 더 쉽다. 반면 designMode는 문서 전체를 편집할 수 있도록 만들기 때문에 메뉴나 내비게이션까지 지워버릴 수도 있고 또 designMode에서는 링크를 클릭해도 이동하지 않기 때문에 지우지 않더라도 동작하지 않는다. 그래서 designMode만 지원하는 브라우저에서는 위지윅 에디터를 만들 때 iframe을 사용한다. iframe 안에 designMode를 켠 문서를 넣고 바깥에 메뉴나 내비게이션이 있는 문서는 designMode를 끈 상태로 놔두는 것이다. 그러면 iframe 영역만 자유롭게 편집할 수 있다. <리스트 2>와 비슷한 식으로 만들면 된다.

<리스트 2> 에디터 기본 틀

<body>
<div>
<a href="...">메뉴1</a>
<a href="...">메뉴2</a>
<a href="...">메뉴3</a>
</div>
<iframe id="editor" onload="this.contentWindow.document. designMode='on';"></iframe>
</body>

<리스트 2>를 실행하면 <화면 3>과 같이 표시된다. 이때, 박스 바깥은 일반 웹페이지처럼 동작하고 박스 안의 영역은 편집 가능한 상태가 된다. 윈도우 프로그래밍으로 비유한다면 RichEdit 컨트롤을 사용할 수 있게 된 셈이다. 하지만 이것만으로는 완전한 에디터가 될 수 없다. 위지윅 상태의 문서를 그 스타일 그대로 글을 쓰거나 지우거나 할 수는 있지만 새로운 스타일로 글을 쓰지는 못하기 때문이다. 예를 들어 World에서 첫 번째 예제 코드의 <p>World</p> 부분을 편집할 때 or 부분을 지우거나 다른 글자로 바꿀 수는 있어도 이 부분만 강조하기 위해 <p>W<strong> or</strong>ld</p>와 같이 만들 수는 없다. 쉽게 말하면 새로운 태그를 삽입할 수단이 없다. 엔터키를 누르면 <p> 태그나 <br>태그가 삽입되는 게 전부이다.


<화면 3> <리스트 2>의 결과화면


<화면 4> tinyMCE

그래서 에디터를 완성하기 위해서는 여러 가지 버튼들을 붙이고 단축키를 할당해서 새로운 태그를 삽입할 수 있게 해야 한다. 다음은 오픈소스 에디터인 tinyMCE의 화면 중 하나인데 이처럼 만들어야 완성된 에디터가 되는 것이다.

 

Bold 버튼 만들기

 

여기서는 간단하게 선택된 부분을 Bold로 강조하는 버튼을 만들어서 붙여보자. 먼저, 윈도우 프로그래밍에서 RichEdit 컨트롤을 쓰려면 갖다 붙이는 것뿐만 아니라 RichEdit 컨트롤의 API를 알아야 하듯이 웹 에디터에서도 웹 브라우저에서 제공하는 에디터의 API를 알아야 한다. 이것도 파이어폭스와 IE가 약간 다르긴 하지만 상당히 비슷한 편이다. 둘 다 document 객체에서 execCommand라는 메소드를 사용할 수 있다. execCommand의 사용법은 다음과 같다.

bSuccess = object.execCommand(sCommand [, bUserInterface] [, vValue])

IE에서는 selection 객체나 range 객체에도 이 메소드를 사용할 수 있다. 첫 번째 sCommand는 실행할 명령의 종류, 두 번째는 UI가 붙느냐 아니냐인데 일단은 무조건 false를 준다고 생각하면 된다. 세 번째는 명령을 실행하는데 부가적으로 필요한 값들을 넘겨주는 것이다. 대부분의 편집 API는 이 execCommand 메소드 하나에서 sCommand를 다양하게 바꿔가면서 실행하게 된다. sCommand의 종류로는 bold, createlink, fontname, fore color, formatblock 등 에디터에 필요한 다양한 것들이 있으며 자세한 내용은 파이어폭스 사이트나 MSDN에서 찾아볼 수 있다.

여기서는 강조하는 버튼을 붙일 것이므로 필요한 커맨드는 bold다. 바로 앞의 예제 코드에서 div 태그 안에 <리스트 3>과 같은 코드를 삽입해보자.

<리스트 3> 강조 버튼

<script type="text/javascript">
function editorDocument() {
return document.getElementById('editor').contentWindow.document
}
</script>
<a href="#" onmousedown="return false;" onclick= "editorDocument().execCommand('bold', false, true); return false;">강조</a>

그리고 웹 브라우저에서 다시 html 파일을 열어보자. 링크가 하나 더 생겼다. 이제 편집을 하다가 강조 링크를 누르면 그 다음부터 입력하는 글자는 진하게 표시될 것이다. 일부분을 선택하고 강조 링크를 누르면 그 부분만 강조된다. 이런 식으로 에디터에 필요한 다양한 기능들을 추가하면 앞서 본 tinyMCE와 같은 웹 에디터를 만들 수 있다.


<화면 5> <리스트 3>의 결과화면

이처럼 생각보다 웹 에디터를 만드는 일이 어렵지 않음을 알 수 있다. 하지만 그렇다고 또 쉬기만 한 일도 아니다. 브라우저마다 동작이 조금씩 다르고 웹 브라우저에 내장된 에디터에 버그가 많기 때문이다. 그래서 tinyMCE 같은 에디터에서는 이런 부분을 많이 수정해 놓았고 필자가 개발에 참여했던 스프링노트에서도 처음에는 tinyMCE를 쓰다가 수많은 버그를 견디지 못하고 에디터를 처음부터 다시 만들기도 했다. 아무튼 이제 사용자들에게 액티브X를 설치하도록 강요하지 않고도 꽤 괜찮은 수준의 위지윅 에디터를 제공할 수 있다는 것은 희망적인 일이다.

 

드래그 앤 드롭 기능 만들기

 

 

웹 페이지 내에서의 드래그 앤 드롭도 자바스크립트와 CSS만으로 구현할 수 있다. 드래그 앤 드롭은 윈도우처럼 웹 브라우저 내의 대화상자를 끌어서 움직인다든지, 트리에서 항목을 끌어서 옮기는 등 다양한 응용이 가능하기 때문에 직관적인 UI를 만드는데 유용하다. 만드는 방법도 어렵지 않다. 우선 CSS에는 절대 좌표로 특정 엘리먼트의 위치를 지정할 수 있는 기능이 있다. 자바스크립트에서는 다음과 같은 코드로 CSS style을 지정할 수 있다.

element.style.top = ‘200px’
element.style.left = ‘150px’

이것은 element를 위에서 200 픽셀, 왼쪽에서 150 픽셀의 위치에 놓으라는 것이다. 이 기능을 이용하면 특정 엘리먼트의 위치를 마음대로 조정할 수 있다. 또, 자바스크립트에서는 마우스 이벤트를 잡아내서 그 지점의 좌표를 알아낼 수 있다. 마우스를 누를 때 mousedown, 움직일 때 mousemove, 뗄 때 mouseup 이벤트가 발생하는데 이것을 이용하면 된다. 좌표는 프로토타입의 이벤트 객체를 통해서 쉽게 가져올 수 있다. 그리고 엘리먼트의 현재 위치도 자바스크립트에서 element.offsetLeft, elem ent.offsetTop 속성으로 알 수 있다. 엘리먼트의 좌표를 읽을 때는 자바스크립트로, 수정할 때는 CSS의 style 속성으로 쓴다는 점에 주의해야 한다. 이 정도만 알면 나머지는 산수만 하면 된다.

 

대화상자 만들기

 

먼저 문서에 대화상자 하나를 그려보자. 이번 예제부터는 프로토타입 라이브러리를 사용할 것이다.

<리스트 4> 대화상자 만들기

<html>
<head>
<script type="text/javascript" src="prototype.js"></script>
<style>
#dialog {

left: 150px;
top: 100px;
padding: 1em;
background-color: lightgreen;
}
</style>
</head>
<body>
<div id="dialog">
Hello
</div>
</body>
</html>

<리스트 4>를 실행시키면 <화면 6>과 같은 화면이 표시될 것이다. 팝업 윈도우가 아니라 HTML 문서 안에 div 태그를 띄워서 마치 대화상자처럼 보이게 만든다.


<화면 6> <리스트 4>의 결과화면

 

이벤트 핸들러 설정하기

 

우리는 여기서 Hello가 있는 대화상자를 마우스로 누르고 움직이면 대화상자가 따라 움직이도록 만들 것이다. 먼저 HTML 문서에 이벤트를 걸어야 한다. Hello가 있는 div 태그에서 마우스를 누르면 드래그가 시작되므로 div 태그에 onmousedown 이벤트 핸들러를 설정한다. 그리고 마우스가 이동하는 범위는 문서 전체이므로 문서 전체에 onmousemove 이벤트 핸들러를 걸고 드래그 종료를 확인하기 위해 onmouseup 이벤트도 문서 전체에 걸어준다. 위의 코드를 다음과 같이 수정하면 된다.

<body onmousemove=“drag($(‘dialog’), event)” onmouseup=“dragEnd($(‘dialog’), event)”>
<div id=“dialog” onmousedown=“dragBegin(this, event)”>

이벤트 핸들러에서 함수를 실행하면서 두 개의 인자를 넘긴다. 첫 번째 인자는 div 태그의 DOM 객체이고 두 번째 인자는 이벤트의 속성을 담고 있는 객체이다. 이벤트 핸들러에서는 이 두 가지 인자를 가지고 조작하게 된다.

 

드래그 이벤트 핸들러 만들기

 

그럼 이제 각 이벤트에 따라 동작하는 실제 이벤트 핸들러 함수를 만들어보자. 먼저 dragBegin에서 해야 할 일은 드래그를 시작한 지점의 좌표를 기억하고 드래그 시작을 알려주는 것이다. 다음과 같은 코드면 충분하다.

<리스트 5> 드래그 시작 알리기

function dragBegin(element, event) {
element.dragging = true
element.startx = Event.pointerX(event)
element.starty = Event.pointerY(event)
}

element 객체에 바로 우리가 정의한 속성을 대입하는 것이 특이해보일 수도 있을 것이다. DOM 객체도 일반 자바스크립트 객체와 똑같이 다룰 수 있고 자바스크립트는 속성을 동적으로 할당할 수 있기 때문에 <리스트 5>와 같은 코드가 가능하다. 보통 DOM 객체에 대응하는 자바스크립트 객체를 proxy 객체로 만들어서 쓰는 경우가 많은데 DOM 객체 자체에 메소드와 속성을 부여해서 실제로 드래그할 수 있는 객체인 것처럼 다룰 수도 있다. 지금은 드래그 앤 드롭의 원리를 보여주는 것이 목적이기 때문에 간편한 이 방법을 선택했지만 상황에 따라 다른 선택이 가능할 것이다.

이제 처음 드래그한 지점은 저장했으니 drag 함수에서는 마우스가 이동한 거리를 계산해서 그만큼 div 태그를 이동시키면 된다. <리스트 6>과 같은 코드가 될 것이다.

<리스트 6> 드래그 함수 적용

function drag(element, event) {
if (!dragging) return
element.style.left = element.offsetLeft + Event.pointerX(event) - element.startx + 'px'
element.style.top = element.offsetTop + Event.pointerY(event) - element.starty + 'px'
element.startx = Event.pointerX(event)
element.starty = Event.pointerY(event)
}

여기까지 하고 실행해보면 이제 Hello가 마우스를 따라다니는 것을 확인할 수 있을 것이다. 이제 마우스 버튼에서 손을 뗐을 때 드래그 안 되도록 하는 코드만 넣으면 된다.

function dragEnd(element, event) {
element.dragging = false
}

이걸로 드래그 앤 드롭의 완성이다. 불과 함수 세 개를 사용한 열 몇 줄의 코드로 드래그 앤 드롭이 구현되는 것이다.

 

드래그 앤 드롭 코드 줄이기

 

산수만 잘한다면 좀 더 줄일 수도 있다. 사실 마우스를 클릭한 지점과 대화상자의 좌상단과의 거리는 늘 일정하게 유지된다. 그렇다면 이 차이만 처음에 구해두면 중간에 변하는 값을 매번 저장하지 않아도 된다. 즉, 다음처럼 코드를 줄일 수 있다.

<리스트 7> 개선된 드래그 앤 드롭 코드

function dragBegin(element, event) {
element.dragging = true
element.diffx = Event.pointerX(event) - $('dialog').offsetLeft
element.diffy = Event.pointerY(event) - $('dialog').offsetTop
}
function drag(element, event) {
if (!element.dragging) return
element.style.left = Event.pointerX(event) - element.diffx + 'px'
element.style.top = Event.pointerY(event) - element.diffy + 'px'
}
function dragEnd(element, event) {
element.dragging = false
}

드래그가 어려운 기술일 것 같지만 의외로 이렇게 간단하게 구현된다. 드롭은 dragEnd에서 다른 함수를 호출할 수 있도록 하는 코드만 조금 추가하면 된다. 이것은 독자의 몫으로 남겨둔다.

또 하나 신경 써야 할 것은 이벤트 핸들러다. 여기서는 간단하게 구현하기 위해 엘리먼트에 직접 이벤트 핸들러를 달았지만 실전에서는 이벤트 핸들러도 동적으로 할당한다. body 엘리먼트처럼 넓은 범위에 mousemove처럼 자주 발생하는 이벤트를 걸어두는 것은 바람직하지 않기 때문이다. 그래서 body에 이벤트를 거는 것은 대화상자에 mousedown 이벤트가 발생한 시점에 걸고 mouseup 이벤트가 발생했을 때 이벤트 핸들러를 제거하는 것이 좋다. dragBegin, dragEnd 함수를 조금만 수정하면 쉽게 할 수 있을 것이다. script.aculo.us 같은 프레임워크에서 드래그 앤 드롭을 구현하는 방법도 크게 다르지 않다. 다만 좀 더 기능이 많기 때문에 코드는 훨씬 긴데 여기 있는 정도의 원리만 이해하면 script.aculo.us의 드래그 앤 드롭 코드도 쉽게 이해하고 활용할 수 있을 것이다.

한 가지 짚고 넘어가야 할 것은 모든 종류의 드래그 앤 드롭이 가능한 것은 아니라는 사실이다. 웹 브라우저의 내장 에디터가 어느 정도 기본 드래그 앤 드롭을 지원하기도 하고 HTML 문서 안에서도 위와 같은 방식으로 드래그 앤 드롭이 가능하지만 클라이언트에 있는 파일의 드래그 앤 드롭과 연계하는 것은 불가능하다. 탐색기에서 이미지를 끌어서 웹 브라우저에 올려놓는다고 이미지가 업로드 되도록 할 수는 없다는 얘기다. 앞서 언급한 것처럼 클라이언트의 자원에는 접근할 수 없기 때문이다. 이런 부분은 역시 클라이언트의 자원에 접근하는 일이기 때문에 액티브X든 자바 애플릿이든 다른 기술을 사용해야한다.

 

 

동적으로 로딩 하는 트리 만들기

 

 

이번에는 좁은 의미의 Ajax인 비동기 통신까지 활용하는 사례를 살펴보자. 트리 컨트롤은 이미 꽤 오래 전부터 액티브X가 아니라 자바스크립트로 구현되어 왔다. 하지만 기존에는 그냥 데이터를 미리 다 로딩해 놓고 보여주는 식이었다. 하지만 Ajax의 등장으로 좀 더 동적인 트리가 가능해졌다. 윈도우에서 탐색기를 열면 처음부터 다 보여주는 것이 아니라 디스크에서 읽은 만큼만 보여주고 다 읽기 전에도 트리를 이용할 수 있다. 이와 같은 동작이 웹에서도 가능하다.

 

트리 만들기

 

먼저 트리부터 만들어보자. 이번에도 프로토타입을 사용한다. 다음과 같은 코드로 최상위 노드로 구성된 트리를 그릴 수 있을 것이다.
일종의 웹사이트 분류 트리를 예제 데이터로 사용해보자. 그리고 각 노드의 하위 노드들도 다음과 같이 샘플 데이터를 만든다.

<리스트 8> 최상위 트리

<ul id="tree">
<li id="search"><span>+ </span>검색</li>
<li id="community"><span>+ </span>커뮤니티</li>
<li id="shopping"><span>+ </span>쇼핑</li>
</ul>

<리스트 9> 트리의 하위 노드

<script type="text/javascript">
var treeData = {
search: [{key:'google', name: '구글'}, {key:'naver', name: '네이버'}, {key:'yahoo', name: '야후'}],
community: [{key:'cyworld', name: '싸이월드'}, {key:'daumcafe', name: '다음 카페'}],
shopping: [{key:'openmarket', name: '오픈 마켓'}, {key:'shoppingmall', name: '쇼핑몰'}],
openmarket: [{key:'gmarket', name: 'G 마켓'}, {key:'auction', name: '옥션'}, {key:'ebay', name: '이베이'}],
shoppingmall: [{key:'cjmall', name: 'CJ Mall'}, {key:'amazon', name: '아마존'}]
}
</script>

treeData 변수에 값들을 넣고 있는데 여기서 사용한 문법이 JSON(JavaScript Object Notation)이다. {}로 둘러싼 부분은 하나의 객체가 되는데 사전과 같은 구조다. {key:’google’, name: ‘구글’}은 key, name이라는 두 개의 속성을 가지며 그 값은 각각 ‘google’과 ‘구글’이 되는 것이다. 자바스크립트는 객체 자체가 다른 언어의 사전 객체나 해시 테이블, 맵 등과 비슷한 역할을 한다. Ajax에서 응답의 자료구조로 흔히 쓰이는 형식이다.

treeData의 내용은 트리 구조를 테이블 형태로 풀어 놓은 것이다. 검색 카테고리는 search라는 id를 갖고 있고 이 아래에는 id가 google, naver, yahoo인 항목들이 있다. 마찬가지로 commu nity도 있고 shopping은 한 단계가 더 있는데 openmarket이 있고 shoppingmall이 있는데 각각은 또 하위 엘리먼트를 가진다.

 

트리 펼치기와 접기

 

그리고 이제 li 엘리먼트 안에 +가 그려진 span 엘리먼트에 클릭 이벤트를 달면 된다. 다음처럼 달면 된다.

$$(‘#tree span’).each(function(element) {
Event.observe(element, ‘click’, toggle)
})

이 코드는 프로토타입이 제공하는 라이브러리를 사용한 것이다. id가 tree인 엘리먼트 밑에 있는 엘리먼트 중 span 엘리먼트를 모두 찾아서 그 각각에 대해서 이벤트를 할당하는 것이다. Event.observe의 의미는 element에 ‘click’ 이벤트가 발생했을 때 toggle 함수를 실행하라는 뜻이다. toggle은 트리의 하위 노드가 접혀 있으면 펼치고, 펼쳐져 있으면 접는 기능을 하면 된다. 이런 기능은 <리스트 10>이면 충분하다.

<리스트 10> toggle 이벤트

function toggle(event) {
var element = Event.element(event).parentNode
if (element.expanded) {
fold(element)
element.expanded = false
} else {
expand(element)
element.expanded = true
}
}

이제 펼치는 expand 함수와 접는 fold 함수만 남았다. expand는 <리스트 11>과 같다.

<리스트 11> expand 함수

function expand(element) {
var ul = document.createElement('ul')
element.appendChild(ul)
var children = treeData[element.id]
children.each(function(child) {
var li = document.createElement('li')
ul.appendChild(li)
li.id = child.key
li.innerHTML = '<span>+ </span>' + child.name
Event.observe(li.firstChild, ‘click’, toggle)
})
element.firstChild.innerHTML = '- '
}

데이터를 가져와서 document.createElement 함수로 엘리먼트를 생성한 후 현재 노드에 appendChild로 갖다 붙이면 된다. 접는 것은 간단하다. 다음과 같이 expand에서 붙였던 엘리먼트들을 죄다 지우면 된다.

function fold(element) {
element.removeChild(element.getElementsByTagName (‘ul’)[0])
element.firstChild.innerHTML = ‘+ ’
}

 

동적 로딩 기능 만들기

 

여기까지만 하면 데이터를 처음에 다 가져와서 트리 구조로 표현하는 것이 되는 것이다. 이제 동적으로 데이터 로딩하는 부분을 추가해보자. expand 함수를 보면 중간에 treeDataelement. id를 통해서 자식 노드들을 배열 형태로 가져오는 코드가 있다. 이 부분에서 Ajax를 통해서 데이터를 가져오게 하면 된다. 다만 비동기로 통신하는 코드는 데이터를 가져오도록 요청하는 부분과 가져온 데이터를 처리하는 부분이 분리가 되어야 한다. expand 함수에서는 데이터를 가져오도록 요청만 하고 데이터를 가져오고 나면 addChildren 함수를 호출되도록 하면 된다. 그럼 <리스트 12>와 같은 코드가 될 것이다.

<리스트 12> addChildren 함수를 이용한 동적 로딩 코드

function expand(element) {
new Ajax.Request('/treeData?id=' + element.id, {
method: get,
onSuccess: addChildren
})
}

function addChildren(request) {
var children = eval(request.responseText)
var ul = document.createElement('ul')
children.each(function(child) {
var li = document.createElement('li')
ul.appendChild(li)
li.id = child.key
li.innerHTML = '<span>+ </span>' + child.name
Event.observe(li.firstChild, 'click', toggle)
})
element.firstChild.innerHTML = '- '
}

Ajax.Request도 프로토타입에서 제공하는 기능이다. 브라우저별로 호출방법이 다른 XMLHttpReqeust 객체를 wrapping 해서 쓰기 편하게 해준다. 여기서 첫 번째 인자가 호출할 URL인데 이 코드가 제대로 동작하려면 서버 사이드의 코드도 필요하다. 하지만 간단하게 텍스트 파일을 만들어서 텍스트 파일 URL을 써 넣고 텍스트 파일 내용에는 JSON 타입으로 내용을 써 놓아서 테스트해볼 수는 있을 것이다.

 

 

재미 있는 Ajax UI 프로그래밍

 

 

몇 가지 예제를 통해 살펴본 것처럼 웹에서 자바스크립트로 기능성 높은 UI를 만드는 일은 그리 어려운 일이 아니다. 게다가 이미 이런 UI 컴포넌트들을 만들어서 모아 놓은 오픈소스 라이브러리도 있다. Dojo같은 프레임워크는 윈도우 프로그래밍 하는 느낌으로 사용할 수 있고 script.aculo.us 같은 프레임워크는 UI 관련된 컴포넌트들을 모아서 제공하고 있다. jQuery는 앞서 살펴본 프로토타입과 script.aculo.us를 합친 기능을 제공한다. 대부분 커스터마이즈하기 쉽게 되어 있기 때문에 별다른 노력 없이 가져다 쓸 수 있을 것이다.
그럼에도 불구하고 이런 UI 컴포넌트를 만드는 방법은 알아둘 필요가 있다. 프레임워크들이 제공하는 것과 비슷하지만 다른 컴포넌트를 만들어야 하는 경우가 많기 때문이다. 예를 들면 스프링노트에서는 트리 목록을 보여주는 사이드 바가 있는데 이 부분의 크기를 마우스 드래그로 조정하는 기능이 있다. 이런 기능은 일반적인 드래그 앤 드롭 컴포넌트로는 붙이기 어렵다. 그럴 때 드래그 앤 드롭의 구현 방법을 알고 있다면 손쉽게 구현할 수 있다.

이미 완성된 컴포넌트를 조립하는 액티브X가 개발이 빠른 측면도 있지만 배포 면에서는 아무래도 개발자나 사용자나 모두에게 불편하다. 반면에 Ajax UI 컴포넌트는 개발이 액티브X에 비해 크게 느리지 않고 배포에는 월등히 유리하다. 접근성의 측면에서도 액티브X나 플래시, 자바 애플릿 등의 다른 기술에 비해 브라우저만 있으면 되는 Ajax 기술이 가장 좋다고 할 수 있다.

하지만 필자가 그보다 더 중요한 장점으로 꼽고 싶은 것은 Ajax 개발은 좀 더 재미있다는 것이다. 자바스크립트는 현재 널리 사용되는 언어 중 가장 다이내믹한 언어이다. 그 덕분에 코드와 생각의 거리가 비교적 짧아서 좋은 코드를 만들 수 있고 다른 UI 개발에 비해 결과를 빨리 확인할 수 있다는 점도 매력적이다. 자바스크립트가 한때는 스파게티 소스의 온상인 것처럼 이야기되기도 했지만 프로그래머가 아닌 사람들도 쉽게 가져다 쓰고 응용할 수 있는 언어임은 부인할 수 없을 것이다. 그리고 동적인 언어는 지저분해질 수 있는 한계도 크지만 더 좋은 코드를 만들 수 있는 한계도 크다. 개발자에게 더 많은 권한을 부여해주는 것이다.

자바스크립트와 CSS 기술의 발전 덕분에 이제 UI 때문에 액티브X를 쓸 필요는 거의 없어졌다. 그럼에도 불구하고 아직 그룹웨어나 SI 분야에서는 액티브X가 많이 쓰이고 있다. 웹 접근성도 해치고 사용자도 귀찮게 만드는 액티브X, UI에서 사용하는 것만이라도 줄여야 하지 않을까. 필자가 이 글을 쓰고 있는 PC의 OS도 리눅스인데 액티브X 때문에 사내 그룹웨어에 접속도 못하는 불편을 겪고 있다. 최근 PC를 새로 구입한 사람들도 윈도우 비스타에서 제대로 사용할 수 없는 사이트가 많아서 어려움을 겪고 있을 것이다. 말도 많고 탈도 많은 액티브X, UI 부분만이라도 Ajax로 대체해 보자. Ajax 프로그래밍이 생각보다 쉽고 재미있다는 것을 독자 여러분도 느끼게 되기를 바란다.

 

 

자바스크립트 개발 도구

 

 

자바스크립트에도 다양한 프레임워크와 개발도구가 있는데 여기서는 프로토타입(prototype)과 파이어버그(Firebug)를 소개해보려고 한다. 프로토타입은 요즘 가장 널리 쓰이는 자바스크립트 프레임워크이다. Ajax 애플리케이션에서 많이 사용하는 패턴 중 언어의 기본적인 부분들을 쉽게 해주는 라이브러리이다. 대표적으로 $() 함수가 있다. 앞선 예제에서 사용했던 코드 중에 다음과 같은 부분은

document.getElementById(‘editor’)

아래와 같이 바꿀 수 있다.

$(‘editor’)

단순한 축약에 불과하지만 실제 개발 과정에서는 정말 큰 편의를 제공한다. 이외에 CSS Selector와 같은 문법으로 엘리먼트의 목록을 가져올 수 있는 $$ 함수도 있고 Event 객체나 Array 객체를 편리하게 다룰 수 있는 방법도 제공한다. 예제를 통해 살펴보자.

var list = [1, 4, 6, 3, 11, 8, 4, 7, 8]
var uniqList = list.uniq() // 중복 원소 제거 [1, 4, 6, 3, 11, 8, 7]

루비에서 많이 사용하는 방식으로 closure를 활용해서 for 루프를 대체할 수도 있다.

list.each(function(element) {
sum = sum + element
})

Event 객체의 경우는 브라우저 호환성을 걱정하지 않고 사용할 수 있는 도구들을 많이 제공한다.

Event.pointerX(event) // IE, 파이어폭스에 상관없이 event가 발생한 마우스 좌표를 가져오면서 스크롤 보정도 해준다.
Event.element(event) // IE의 event.srcElement, Firefox의 event.targetElement

자세한 내용은 prototypejs.org에서 볼 수 있다. 요즘은 jQuery라는 프레임워크도 뜨고 있지만 프로토타입이 워낙 빠른 속도로 대중화되어서 많은 다른 라이브러리가 프로토타입 기반으로 되어 있기 때문에 알아두면 좋을 것이다.

일반적으로 복잡한 Ajax 애플리케이션을 개발할 때는 디버깅 도구가 좀 더 많고 표준 지원이 좋은 파이어폭스 기준으로 개발하는 경우가 많다. 파이어폭스에는 자바스크립트 콘솔, Web Developer 툴바, DOM Inspector 등 개발에 편리한 도구가 많다. 그 중 가장 중요한 도구는 아마 파이어버그일 것이다. DOM 구조를 실시간으로 보면서 각종 속성들을 쉽게 볼 수 있고 내용을 바꿀 수도 있기 때문이다. 자바스크립트도 자동완성이 지원되는 shell이 제공되며 간단한 디버깅도 가능하고 에러가 났을 때 정확한 지점을 표시해 주기도 한다. IE에도 최근 MS가 내놓은 IE Dev Toolbar가 있긴 하지만 파이어버그의 기능이 압도적이다.

파이어버그의 DOM Inspector

 


 

출처명 : 한국마이크로소프트 [2007년 6월호]
 

더 큰 세상으로 가는 문 액티브X 대체기술

 

기획/정리 l 전희용 기자 flytgr@imaso.co.kr

 

마소 독자치고 액티브X 문제와 무관하다고 할 수 있는 사람은 별로 없을 것이다. 그런데, 참 이상한 일은 액티브X 이야기만 나오면 문제의 원인이나 해결책을 이야기하기 보단 목에 핏대부터 세운다. 누군가를 탓하기 위함이다. 하지만 막상 따지고 보면 누구의 잘못이라고 하기는 어려운 일이다. 워낙 오랫동안 쌓아온 일이기 때문이다.
그렇다고 곪을 대로 곪은 상처를 그냥 놓아둘 수도 없는 일. 이번 달 특집에서는 이 상처의 원인에 대해 알아보고, 그 치료방법인 액티브X의 대체 기술들에 대해서도 함께 알아본다. 다들 잘 알다시피 아직 액티브X를 1대1로 대신해 줄 수 있는 기술은 없다. 하지만, 여러 기술들을 이용하여 산적한 문제들을 보완하며 차츰 치료해 나갈 수는 있을 것이다. 깊이 박힌 상처가 하루아침에 낫는 걸 보았는가?

 

1부 | 백조에서 미운오리로 전락한 액티브X 문제와 해결방안 | 정희용

2부 | 발등의 불끄기 공인인증서 대체기술 | 최상훈

3부 | UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발 | 박영록

4부 | 액티브X 뛰어넘는 기능과 호환성 XPCOM 개발전략 | 김민수

5부 | MS가 내놓은 액티브X의 대안 실버라이트 활용법 | 한용희

 

발등의 불끄기 공인인증서 대체 기술

 

액티브X 문제는 공인인증서에서 특히 심각하다. 직접 돈을 거래하는데 사용될뿐 아니라 이미 너무 많이 사용하고 있기 때문이다. 게다가 웹 표준화 단체인 오픈 웹의 금융결제원을 상대로 한 거액 소송 덕분에 액티브X로 만든 공인인증서를 다른 기술로 대체하자는 목소리 또한 높아졌다. 특집 2부에서는 공인인증서 대체 기술로 거론되고 있는 기술 중 자바 공인인증서에 대해 간단히 알아본다.

 

최상훈 | vicdev@magicn.com | 다날㈜ 해외개발팀 팀장

 

어느 날 부터인가 액티브X 문제가 여기저기서 터져 나오기 시작하더니, 이제는 일반인들조차도 이 문제에 관심을 가지는 상황이 되었다. 문제는 그렇게 열을 올리고 있으면서도 대체 왜 문제인지 잘 모르는 사람들도 있다는 데 있다. 심지어 그저 반MS 감정의 연장쯤으로 생각하는 사람들도 있기에 1부에서는 먼저 액티브X 문제가 불거지게 된 배경과 그 해결 방법으로 제시되는 기술들에 대해 알아볼 것이다.

 

지금까지 전자결제나 공인인증서 처리에는 액티브X 기술이 독점적으로 사용되어 왔다. 하지만 마이크로소프트(이하 MS)의 독점 기술인 액티브X는 다른 기종의 웹브라우저나 다른 OS 플랫폼에서는 전혀 동작하지 않는다. 예전부터 리눅스나 매킨토시 등 다른 운영체제를 사용하는 사용자 모임에서는 이 문제를 끊임없이 제기해왔다. 급기야 노무현 대통령에게 리눅스 선물하기 모임(줄여서 ‘노리추’라고도 함)이 결성되기 까지 했다. 이 모임은 액티브X 일변도인 인터넷 환경에서 다른 플랫폼을 사용하는 것이 얼마나 불편한지를 정부에 호소하기 위해 2005년 4월 22일 국민 참여 수석을 통해 리눅스가 설치된 컴퓨터를 대통령에게 전달하기도 했다. 이런 노력들이 있었음에도 불구하고 대다수의 윈도우 사용자와 정부는 큰 반응을 보이지 않았다.

 

 

공인인증서 구현 기술들에 대한 고찰

 

 

그런데, 왜 최근 들어서 갑자기 액티브X 이외의 다른 기술로 공인인증서를 처리하는 것에 대한 관심이 급부상하고 있는 것일까? 그 이유는 MS가 윈도우 비스타를 출시하면서 스스로가 제안한 액티브X를 부정했기 때문이다. 더 정확히 말하면 IE7에서 제공하는 보호모드 기능 때문이다. IE7의 보호모드 기능은 [Win dows]나 [Program Files] 등의 시스템 폴더에 파일이 저장되지 않도록 차단하는 기능이다. 그렇다고 시스템 폴더로의 접근이 완전히 차단된 것은 아니다. 일단 IE7을 실행하면 표준 사용자 권한에서 실행된다. 만약 사용자가 IE7을 통해 합법적 시스템 폴더의 접근을 시도할 경우 관리자 권한을 획득하기 위해 윈도우에 권한 상승을 요청하여 사용자의 확인을 받게 하면 접근할 수 있다.

MS에서 보호모드 기능을 제공하는 이유는 액티브X가 상당히 편리한 웹 클라이언트 환경이지만, 보안상 취약한 부분을 내제하고 있기 때문이다. 액티브X를 악용하면 PC에 개인 정보가 노출될 수 있다. 바이러스가 유포되고 원하지 않는 플러그인들이 설치되기도 하며, 컴퓨터 속도를 떨어뜨리는 ‘그레이웨어’의 유포 등 액티브X의 사용자에게 정신적, 물리적, 경제적 피해를 주는 사례가 많았다. 이러한 이유들 때문에 윈도우 비스타(IE 7)의 개발 스펙에 보호모드 기능을 추가한 것이다.

또 다른 이유로 비 MS나 비 IE 사용자들의 불편함이 주무부처에 공감대를 얻은 것으로 해석된다. 물론 그 동안 이런 민원들에 대한 적극적인 응대는 없었다. 앞서 언급한 노리추 사건과 지난 2007년 1월 23일 대한민국 전자정부 웹페이지 국제 표준화 운동을 주도하고 있는 오픈웹(http://openweb.or.kr)이 금융결제원을 상대로 4억 1,500만원의 손해배상 청구한 사건도 있었다.

이러한 일련의 사건과 현상들이 종합되어 개발자가 아닌 사람들까지도 액티브X에 대한 관심을 가지게 되었다. 그 결과 운영체제나 브라우저에 독립적인 공인인증서 처리 애플리케이션이 시대적인 요구로 자리 잡게 된 것이다. 한국정보보호진흥원(이하 KISA)에서는 여러 대안 플랫폼 중 자바 플랫폼을 이용하여 공인인증서를 만드는데 대한 기술을 검토하고 있다.

 

 

기술적 쟁점

 

 

사실 자바 공인인증서 처리 애플리케이션은 스페인과 미국, 독일, 덴마크, 핀란드, 대만 등 많은 국가에서 채택하고 있다. 하지만 국가마다 환경이 다르고, 무엇보다도 공인인증서 처리는 주로 금융 결제 및 인증과 같이 중요하고 민감한 거래에 사용된다. 때문에 개인의 권익을 최대한 보장 받을 수 있도록 안정성을 보장하는 기술검토가 필요하다.

여기에서는 자바로 공인인증서 처리 애플리케이션을 만들기 위해 고려해야 하는 기술 쟁점들에 대해 알아본다.

 

기술적 쟁점 1 - JRE의 비용

 

자바는 반 컴파일 + 반 인터프리터(half-compiled and half-interpreted) 언어다. 때문에 런타임에 자바의 실행을 지원하는 환경이 갖추어져 있어야 한다. 이 환경을 JRE(Java Runtime Environment)라고 하는데, 자바 공인인증서를 처리하려면 JRE가 반드시 설치되어 있어야 한다. 그렇다면 JRE를 설치하면 될 문제다. 하지만 JRE는 몇 가지 문제점을 가지고 있다.

● 설치비용
네트워크로 JRE 설치 파일을 다운 받아 설치가 완료되기까지 작게는 수분 길게는 수십 분 이상의 시간적 비용이 따른다. 물론 이 설치는 한번만 해주면 된다. 또한, 설치 시 엔드 유저에게 낯선 몇 번의 클릭을 해야만 한다.

● JRE의 호환성
호환성은 다시 버전 별 호환성과 운영체제별 호환성으로 나눌 수 있다. 버전 별 호환성은 특정 상위 버전으로 설치를 권장하면 된다. 문제는 운영체제 별 호환성이다. 현재 썬마이크로시스템즈(이하 썬)에서 제공하는 공식 JRE(http://java.sun.com/)는 윈도우와 솔라리스, 리눅스 밖에 없다. 물론 IBM이나 애플 등 여러 OS 벤더들은 각자의 운영체제에 동작하는 JRE를 개발하고 배포한다. 하지만, 운영체제의 JRE 지원은 반드시 보장되는 것이 아니며, 운영체제에서 동작하는 JRE의 호환성도 확보되어야 한다. 하지만 애초에 자바는 WORA(Write Once, Run Anywhere)를 모토로 하는 언어이기 때문에 문제될 게 없으나 벤더의 표준화에 대한 보증이 담보되어야한다.

 

기술적 쟁점 2 - 자바 역공학의 문제

 

앞서 설명한대로 자바는 반 컴파일과 반 인터프리터 언어이기 때문에 자바는 컴파일 하기도 인터프리트하기도 용이한 언어다. 대부분의 경우 이런 자바의 특징은 장점이다. 그런데 이 장점은 반대로 역공학 하기 쉽다는 단점이 되기도 한다. 소스코드를 컴파일하면 곧바로 기계어로 실행할 수 있는 바이너리코드가 생성되는 것이 아니라, JVM이 실행하기 쉬운 바이트코드로 생성되기 때문이다.

현재 바이트 코드 to 소스코드로 역컴파일할 수 있는 툴들은 많이 나와 있는 상태다. 상황이 이러하니 자바 공인인증서 처리 모듈을 만들더라도 쉽게 그 소스를 볼 수 있게 되는 셈이다. 그렇다고 자바로 만들면 전부 역컴파일 된다고 생각할 필요는 없다. 암호화/복호화를 처리하는 코드는 조금의 노력만 투자한다면 쉽게 찾아볼 수 있기 때문이다. 또한, 우리나라에서 사용하는 공식 암호화 알고리즘이 SEED와 3-DES라는 것도 쉽게 알 수 있다(이 문서만 봐도 알 수 있지 않은가?). 문제는 암호화 알고리즘이 무엇이고 코드가 어떻다는데 있지 않다.

일단 PKI(Public Key Infrastructure) 기반의 암호화 및 인증 처리는 알고리즘이 중요한 게 아니라 개인키가 보호되는데 있다. 개인키 정보가 있는 인증서를 확보하지 못 한다면 알고리즘을 알아도 아무런 소용이 없다. 뿐만 아니라 자바 기술에서 역컴파일러의 발전만 있었던 게 아니라 난독기(obfuscator)도 발전했다. 그 덕분에 문자열 인코딩이나 제어흐름을 변경하는 정도의 기능으로도 충분히 역컴파일된 코드를 읽기 힘든 수준의 난독성으로 보장할 수 있다(물론 인내심이 강한 사람에겐 못 당하지만 말이다).

또, 역 컴파일의 문제가 자바만의 문제는 아니다. 액티브X도 역 컴파일의 위험에서 자유로울 수 없는 탓이다. 컴파일되어 배포되는 액티브X 코드도 어셈블리어로 역 컴파일 될 수 있기 때문이다. 어셈블리어를 가독성 높은 고급언어인 자바처럼 쉽게 읽는 사람은 많지 않지만 액티브X도 완벽히 로직을 은닉한다고 할 수 없는 셈이다.

 

기술적 쟁점 3 - 클래스 바꿔치기

 

지금까지의 문제는 나름대로 심각하지 않거나 대안이 있다. 하지만 이제부터의 문제는 좀 더 심각한 편이다.

자바 애플릿은 수행속도를 높이기 위해 매번 실행 시 마다 서버에서 jar 파일을 다운 받아 실행하지 않고 다운받은 jar 파일을 로컬 캐시에 저장해둔다. 캐시 된 jar가 저장될 위치는 Windows의 경우 [제어판] → [자바] → [일반] → [임시 인터넷 파일] → [설정]에서 확인할 수 있다. 물론 실행 시 마다 서버에서 다운로드를 받을 수도 있지만 인증서 처리 같이 사이즈가 큰 코드는 이 방식을 채택할 경우 시간적 비용 부담이 커진다.

캐시 디렉토리에 있는 jar 파일의 압축을 풀면 공격자가 주요 클래스를 자신이 만든 다른 클래스로 바꿔치기 할 수 있다. 만일 바꿔치기한 클래스가 동일한 로직을 수행하면서 아이디와 패스워드, 인증서 텍스트, 주민등록 번호 등을 공격자의 컴퓨터로 저장한다면 그 원래 사용자가 경제적으로 막대한 피해를 입게 될 것은 당연한 일이다.

이때 보안을 위해 Signed Applet을 사용한다 하더라도 큰 도움이 되지 않는다. Signed Applet은 Applet을 실행할 때 인증처리만 할 뿐이지 jar 파일의 변경을 감지하지는 못 하기 때문에 바꿔치기 된 클래스를 그대로 실행할 수 있다. 참고로, 이 사실은 금융결제원 전자인증센터에서 증명되었다.

이 취약점은 자바 자체로는 해결하기 어려운 문제이다. CRC 처리를 한다던가, jar 파일에 변조를 감지하도록 sign을 한다던가, 특정 주요 클래스를 캐시하지 않고 동적 로딩 하는 방법도 생각해봤다. 하지만 ‘클래스 바꿔 치기’ 공격은 자바로 구현된 어떤 클래스에서도 시도할 수 있기 때문에 자바의 문제를 해결하는 자바 클래스는 동일한 문제를 해결할 수 없었다. 이 문제도 약간의 테크닉을 통해 해결할 수 있을 것 같다. 필자가 생각해둔 테크닉이 있지만 이 글에서 표현할 수는 없어 이 정도로 밝혀두겠다.

앞에서도 설명했지만, 이 부분도 액티브X에서 완벽히 해결된 사항이 아니다. 필자는 윈도우 실행파일을 역 어셈블하여 사용 기간이 제한된 셰어웨어의 만료일을 체크하지 않도록 해당 코드를 JUMP 시켰던 동료를 본 적이 있다. 액티브X도 변조가 가능하다는 얘기다. 문제는 자바 클래스를 변조해 바꿀 수 있는 사람보다 액티브X의 바이너리를 변조할 수 있는 사람이 압도적으로 적다는데 있다.

 

기술적 쟁점 4 - PKCS#11 지원 문제

 

자바에서는 암/복호화 처리를 위해 JCA(Java Cryptography Architecture)와 JCE(Java Cryptography Extension)를 정의하고 있다. JCA는 java.security 패키지에 있으며, 암호화 처리를 위한 메커니즘과 구조, 인터페이스, 팩토리 등을 정의하고 있다. 암호화 처리는 상당히 다양한 알고리즘을 사용할 수 있어서(혹은 어떠한 알고리즘을 사용하는지 알 수 없어서) SPI(Service Provider Interface)를 이용하고 있다. 왜냐하면 자바는 사용자가 사용할 알고리즘을 알 수 없고 사용자가 사용할 수 있는 모든 알고리즘을 제공할 수 없기 때문이다. 그래서 JCA는 SPI의 프로바이더를 이용하여 사용자가 사용할 암호화 방식을 등록/선택하게 하므로 어떤 알고리즘이던지 사용할 수 있는 틀을 제공한다.

JCE는 java.crypto 패키지에 있으며, JCA의 확장으로 1.2 버전까지는 미국의 수출제약법령(U.S. export control regulat ions)에 의해 미국과 캐나다 내에서만 사용할 수 있었다. 그러나 JCE 1.2.2 부터는 제한적인 상황에서 미국과 캐나 다 이외 지역에서도 사용할 수 있게 되었다.

여하튼, JCE는 Cipher와 MAC(Message Authentication Code), Key Generation, Key Agreement 등 실제적인 암호화 처리를 제공한다. 보다 자세한 설명은 자바서비스넷의 이인영님이 게시한 Java Security와 Cryptography Architecture 문서(http://www.javastudy.co.kr/docs/lec_java/security/JAVASecurity.html)를 참조하길 바란다. 따라서 JCA와 JCE의 기능은 각각 <그림 2>와 같다.

PKCS는 RSA 사의 연구실에서 주관하여 정의한 공개키 암호화 표준(Public Key Crpytography Standard)이다. 이 표준은 공개키 암호화를 위한 각종 방식을 정의하고 있는데 PKCS#1 부터 PKCS#15 까지 15 종류의 표준이 있다. PKCS#11은 11번째 표준으로서 암호화 토큰 인터페이스 표준을 정의하고 있다.

자바SE 5.0에서 자바 플랫폼에서 네이티브 PKCS#11 토큰의 통합을 편리하게 하기 위해 Sun PKCS#11 프로바이더를 추가하였다. 이 프로바이더는 JCA와 JCE API로 작성된 기존의 응용프로그램이 네이티브 PKCS#11 토큰에 접근할 수 있도록 해준다. 자세한 정보는 http://java.sun.com/javase/6/docs/ technotes/guides/security/p11guide.html을 참조하길 바란다.

● HSM 보안 토큰
공인인증서의 해킹 사고를 막기 위해 이를 별도의 하드웨어에 저장할 목적으로 HSM(Hardware Security Module) 보안 토큰을 이용한다. 왜냐하면 HSM은 하드웨어 암호 가속기나 스마트카드 같은 암호 토큰과의 네이티브 프로그래밍 인터페이스를 제공하기 때문이다. 따라서 여러 종류의 디바이스에 대한 하드웨어 암호화를 이용하기 위해 HSM을 사용해야 하는데, 이때 PKCS#11 프로바이더를 이용한다. 따라서 자바 5.0 이상에서는 기본적으로 PKCS#11 프로바이더를 사용할 수 있다.

PKCS#11 지원은 디바이스 업체에서 PKCS#11 라이브러리를 제공하면 자바에서는 해당 프로바이더를 이용하여 기능호출이 가능하다. 하지만, PKCS#11 프로바이더 이용 시 SEED 알고리즘을 지원하지 않기 때문에 이에 대한 처리방안을 고려해야 한다.

왜냐하면, SEED 알고리즘은 1999년 한국정보보호센터(현 한국정보보호진흥원)에서 개발한 우리나 라 고유의 알고리즘이기 때문이다. 따라서 SEED 알고리즘을 별도로 Cipher클래스를 상속하여 구현하고 PKCS#11 프로바이더에 등록해주면 문제는 해결될 것이다.

 

기술적 쟁점 5 - 윈도우 비스타 환경에서의 공인인증서 저장위치 문제

 

현재 우리나라에서 공인인증서를 저장하는 위치는 PC에서 시스템 폴더 밑에 특정 폴더로 지정되어 있다. 그렇다면 앞서 윈도우 비스타의 IE 7에서 발생한 문제와 동일한 문제가 발생한다. 필자가 가능성 검증을 하지는 못 했지만 이 문제는 자바에서 권한상승 방법을 그대로 이용하면 되지 않을까 싶다. 자바에 기본적으로 내장된 CORBA를 사용해 COM/CORBA Bridge 기술을 적용하는 것도 좋은 방법일 듯하다. 이 방법은 CORBA와 COM의 상호 운용성을 제공한다.
자바가 공인인증서 플랫폼으로 쓰인다면?

이상에서 밝혀졌다시피 자바는 공인인증서 처리 플랫폼으로 사용하는데 장/단점을 자기고 있다. 하지만, 자바가 공인인증서를 처리하는데 충분히 적합하며, 결함이 없다는 데에는 이견이 없을 것이다. 단지 JRE를 엔드유저가 다운 받아야 하고 수행속도도 느릴 수 있다.

파업의 천국 프랑스에서 대중교통 노동자들에 의해 파리에서 3주 동안 지하철과 기차, 시내버스가 단 한 대도 다니지 않았다고 한다. 이때 불편함을 묻는 기자의 질문에 과반수가 넘는 파리 시민이 “불편하지요. 하지만 나는 파업 노동자들을 100% 지지하고 있습니다”라고 답했다고 한다. 자바를 공인인증서 처리 모듈로 사용하기 위해서는 최초 한번 JRE를 깔고 또다시 애플릿을 다운로드해야 하는 부담이 따른다. 하지만 액티브X가 지원되지 않으므로 고생하는 윈도우가 아닌 운영체제, IE가 아닌 웹브라우저 사용자들까지 공인인증서를 사용할 수 있다면 충분히 감내할 수 있는 부담이 아닐까 한다.

 

Cover Story Plus

 

오픈웹 소송과 자바 공인인증서

 

특집 2부는 자바로 공인인증서를 만들기 위해 필요한 기술과 해결 과제 등의 기술 쟁점을 소개하고 있다. 대체 왜 이런 복잡하고 어려운 기술에 대해 설명하고 있는 것일까? 그것에 대해 이해하기 위해 먼저 오픈웹 소송 과정부터 살펴보자.
액티브X 문제가 지속적으로 제기되어 왔지만 오랜 시간동안 그저 산발적이고 미약한 목소리들 탓에 큰 성과를 거둔 적은 별로 없었다. 그러다가 비스타 발표와 맞물려 웹 표준화 단체인 오픈웹(www.openweb.or.kr)이 심지에 불을 붙이며 액티브X, 그중에서도 공인인증서 문제에 불이 붙었다.

오픈웹의 소송 내용은 금융결제원(이하 금결원)이 특정 운영체제와 브라우저에서만 실행할 수 있는 공인인증서를 제공함으로써 윈도우와 IE를 사용하지 않는 사용자들을 차별했다는 내용이 주였다. 액티브X로 만들어진 공인인증서를 사용하고 있는 탓이다. 이러한 차별을 통해 그동안 피해를 입었다고 주장하는 83명의 원고인단과 함께 금결원을 상대로 손해배상 청구 소송을 한 것이다. 3%를 밑도는 소수 운영체제나 브라우저를 쓰는 사람들은 대한민국에서 인터넷 뱅킹조차 할 수 없도록 만들었으니 당연한 일일 터다.

 

잇따른 소송과 반발

 

그런데 오픈웹이 깃발을 들어 올리자 여기저기서 또 다른 목소리들이 터져 나왔다. 금결원이 그동안 특정 OS와 브라우저만 지원하는 인증서를 강요한 탓에 자신들이 범용적으로 사용할 수 있도록 개발한 공인인증서 소프트웨어를 사용하지 못하여 경제적 손실을 입었다며 한 결제 대행 서비스 업체도 소송 의사를 밝혔다. 더불어 오픈웹 소송 결과가 긍정적으로 진행되어가자 이번에는 아예 금결원은 공인인증 기관으로서의 자격이 없다며 공인인증기관 지정 취소 요구 소송을 준비하고 있다. 금결원이 은행들의 필요에 따라 만들어졌으며 은행의 임원들이 이사진으로 구성된 금결원이 공인인증 기관으로 활동하는 것에 문제가 있다는 것이 오픈웹의 주장이다. 또, 소송 과정에서 금결원은 은행의 추가비용 발생 등을 이유로 IE 이외의 브라우저 사용자를 위한 공인인증 소프트웨어 제공을 거부하는 등 공인인증기관으로서의 역할을 충실히 하지 않고 있다는 점도 이유로 들고 있다. 이런 이유로 오픈웹은 6월경에 공인인증기관 지정을 담당하는 정보통신부를 상대로 금결원에 대한 공인인증 기관 지정의 취소를 요구하는 행정 소송을 제기할 방침이란다.

 

공인인증서 문제 자바로 해결하자

 

오픈웹 소송으로 액티브X 공인인증서 문제가 주목을 받자 한국정보보호진흥원(이하 KISA)이 발 벗고 나섰다. KISA는 지난 2월부터 관련 전문가들과 함께 범용적으로 사용할 수 있는 공인인증서를 만들기 위한 방안을 모색하고 있다.

이미 몇 차례 회의를 가진 끝에 내린 결론은 여러 방법 중 해외에서도 오픈소스를 통해 서비스를 구현하고 있는 자바가 가장 유력한 기술로 인정되고 있다. 자바는 JRE(Java runtime environment)만 설치되어 있는 환경이면 OS와 브라우저를 가리지 않고 지원한다. 반면에 기존의 액티브X 윈도우 계열의 OS와 IE에서만 작동하는 기술이기 때문에 비MS 계열의 PC 환경에서는 사용이 불가능한 상태이다.

물론, 자바를 이용한 공인인증 서비스 구현이 하루아침에 될 일은 아니다. 이런 서비스가 구현되려면 먼저 다양한 사용자 환경에 대한 지원과 국제 표준을 준용한 인증서 관리 기능 지원 여부, 국제 및 국내 표준 알고리즘(SEED 알고리즘)을 이용한 전자서명 생성과 검증, 암복호화 기능 지원, 스마트카드와 USB 보안토큰 장치 지원 등이 필요하다.

최근 KISA와 관련 전문가들은 자바의 보안성과 확장성을 중심으로 기술적인 검토를 하고 있으며, 비스타와의 호환성 등 여러 가지 문제에 대한 해결책도 모색 중이다.

이미 해외의 몇 개 나라에서는 자바를 이용하여 공인인증 서비스를 구현하고 있기도 하다. KISA와 전문가들의 노력, 사회의 관심 그리고 금융기관의 바른 의식이 하나가 되어 조만간 자바 공인인증 서비스를 만날 수 있게 되기를 바란다.

정희용 기자 | flytgr@imaso.co.kr

Cover Story Plus

 

공인인증서 문제 해결을 위한 방법들

 

특집 2부에서는 공인인증서 문제를 해결하기 위해 자바를 활용하는 방법 위주로 설명하고 있지만, 이 밖에도 여러 가지 방법들이 제안되고 있다. 특히, 오픈웹은 상당히 다양한 방법들에 대해 체계적으로 제시하고 있으며, 이는 다시 단기적인 방법과 장기적인 방법으로 나누어서 설명되고 있다. 오픈웹이 제시하고 있는 단기적 해결 방법과 장기적인 해결 방법은 다음 링크를 통해 확인할 수 있다.

● 단기적 해결 방안 : http://korea.gnu.org/openweb/1/sterm.html
● 장기적 해결 방안 : http://open.unfix.net/%EC%A0%84%EC%9E %90%EC%84%9C%EB%AA%85%EB%B2%95%EA%B3%BC-%EA%B3%B5%EC%9D%B8%EC%9D%B8%EC%A6%9D%EC%84%9Cin-progress/#c9

여기에서는 오픈웹이 제안하고 있는 해결 방법들에 대해 간단히 알아본다. 먼저 단기적인 해결 방안으로 제시하고 있는 기술들은 자바 애플릿과 특집 4부에서 다루고 있는 XPCOM, 플래시(플랙스)와 자바 애플릿의 병행, 플래시, 모질라나 넷스케이프의 플러그인 기능 등이다. 이 중에서 가장 빨리 적용할 수 있는 방법으로는 자바 애플릿과 플래시를 들고 있다.

자바 애플릿에 대해서는 본문에서 설명하고 있지만 다시 간단히 설명하자면, 자바는 높은 수준의 보안을 확보할 수 있을 뿐 아니라 플랫폼에 구애받지 않으면서 인증서를 구현할 수 있다. 또 한 가지 빼놓을 수 없는 장점은 사용자가 컴퓨터에 관리자 권한으로 어떤 프로그램도 설치할 필요가 없기 때문에, 네트워크 관리 기준이 높은 외국에서도 쉽게 사용할 수 있다는 점이다. 물론, 자바 애플릿에도 단점은 있다. 컴퓨터가 자바 애플릿을 다운 받는데 약간의 시간이 걸린다는 점과 가상머신이 마련되는 동안 좀 더 기다려야 한다는 점이다.

다음은 플래시다. 플래시는 자바 애플릿에 비해 내려 받아야 하는 파일의 크기가 작고 플래시 플레이어 자체가 가상머신의 역할을 하기 때문에 자바 애플릿을 쓸 때보다는 시간이 덜 걸린다는 장점이 있다. 또, 높은 안정성을 가지고 있을 뿐 아니라 플래시 플레이어만 설치되어 있다면 매킨토시와 리눅스 등의 운영체제에서도 사용할 수 있다. 관리자 권한이 없는 일반 사용자가 자신의 개인용 파일 시스템에 플래시 플레이어를 설치하는 구조이기 때문에, 보안 위험을 줄이면서도 추가 설치나 업그레이드가 가능하다는 점도 장점이다. 오픈웹에 따르면 이미 국내 보안 업체 중에 플래시와 자바 애플릿을 이용한 공인인증서 처리 솔루션의 개발을 완료한 곳도 있단다.

한 가지를 더 살펴보자. 이번 방법은 브라우저의 확장 플러그인을 사용하는 것이다. 플러그인은 애플릿처럼 어떤 응용프로그램의 이용에 도움이 되는 특정한 부가 기능을 제공하는 보조 프로그램이다. 여기에서 주프로그램과 보조 프로그램 간의 통신과 리소스 호출 방법 등을 제시하는 API는 오픈소스 형태로 공개되어 있다. 대표적인 브라우저로는 파이어폭스가 있으며 플러그인 기반의 인증 기술 또한 국내 기술진에 의해 개발되어 있다고 한다.

다음 표는 오픈웹에서 제안하고 있는 공인인증서 문제의 단기적인 해결 방법들을 비교 정리한 것이다.

(자세히 보기 - 이미지를 클릭 하십시오.)

정희용 기자 | flytgr@imaso.co.kr

 


 

출처명 : 한국마이크로소프트 [2007년 6월호]
 

더 큰 세상으로 가는 문 액티브X 대체기술

 

기획/정리 l 전희용 기자 flytgr@imaso.co.kr

 

마소 독자치고 액티브X 문제와 무관하다고 할 수 있는 사람은 별로 없을 것이다. 그런데, 참 이상한 일은 액티브X 이야기만 나오면 문제의 원인이나 해결책을 이야기하기 보단 목에 핏대부터 세운다. 누군가를 탓하기 위함이다. 하지만 막상 따지고 보면 누구의 잘못이라고 하기는 어려운 일이다. 워낙 오랫동안 쌓아온 일이기 때문이다.
그렇다고 곪을 대로 곪은 상처를 그냥 놓아둘 수도 없는 일. 이번 달 특집에서는 이 상처의 원인에 대해 알아보고, 그 치료방법인 액티브X의 대체 기술들에 대해서도 함께 알아본다. 다들 잘 알다시피 아직 액티브X를 1대1로 대신해 줄 수 있는 기술은 없다. 하지만, 여러 기술들을 이용하여 산적한 문제들을 보완하며 차츰 치료해 나갈 수는 있을 것이다. 깊이 박힌 상처가 하루아침에 낫는 걸 보았는가?

 

1부 | 백조에서 미운오리로 전락한 액티브X 문제와 해결방안 | 정희용

2부 | 발등의 불끄기 공인인증서 대체기술 | 최상훈

3부 | UI 대체는 내게 맡겨라 Ajax를 이용한 UI 개발 | 박영록

4부 | 액티브X 뛰어넘는 기능과 호환성 XPCOM 개발전략 | 김민수

5부 | MS가 내놓은 액티브X의 대안 실버라이트 활용법 | 한용희

 

백조에서 미운오리로 전략한 액티브X의 문제와 해결방안

 

샌프란시스코에서 열리는 자바원 컨퍼런스 2007에서 자바의 아버지 제임스 고슬링을 만난 기자는 한국의 액티브X 문제에 대해 이야기하고, 조언을 구하고자 했다. 하지만 이는 생각보다 훨씬 어려운 일이었다. 한국의 사례가 워낙 독특한 탓에 짧은 영어실력으로는 도저히 우리의 상황조차 이해시키기 어려웠던 탓이다. 특집 1부에서는 우리가 맞게 된 액티브X 문제를 되돌아보고 그 해결 방안들을 찾아본다.

 

정희용 기자 | flytgr@imaso.co.kr

 

어느 날 부터인가 액티브X 문제가 여기저기서 터져 나오기 시작하더니, 이제는 일반인들조차도 이 문제에 관심을 가지는 상황이 되었다. 문제는 그렇게 열을 올리고 있으면서도 대체 왜 문제인지 잘 모르는 사람들도 있다는 데 있다. 심지어 그저 반MS 감정의 연장쯤으로 생각하는 사람들도 있기에 1부에서는 먼저 액티브X 문제가 불거지게 된 배경과 그 해결 방법으로 제시되는 기술들에 대해 알아볼 것이다.

 

 

액티브X 문제의 배경

 

 

마소 독자치고 IMF라는 말이 곱게 들리는 사람은 없을 것이다. 1990년대 말 우리나라는 외환위기를 겪으면서 경제적으로 큰 타격을 입었다. 외국에 빚을 많이 지게 된 우리나라는 부채를 갚기 위해 특단의 조치가 필요하였다. 우리나라의 신 성장 동력을 찾기 위해 국가가 발 벗고 나서야만 했다. 이때 선택한 국가 원동력 중에 하나가 바로 IT산업이다. 독자들 중에도 이때의 IT 붐에 편승하여 전공을 선택하거나 개발자가 된 사람도 있을 것이다. 이맘때쯤 전국적으로 초고속 인터넷망이 설치되면서 인터넷 붐이 일어났고, 모든 것은 인터넷으로 통했다. 바야흐로 전자상거래의 본격적인 태동이 시작된 것이다. 전자상거래를 이용하여 금융거래를 안전하게 할 수 있으려면 강력한 보안이 필수적이었다. 하지만 그 당시의 브라우저는 요즘처럼 강력한 128bit 암호화 기능을 자체적으로 제공하고 있지 않았다.

 

암호화 기술로 채택된 액티브X

 

결국 보안 기술을 따로 만들어야 했지만, 미국은 선뜻 128bit 암호화 기술을 내주지 않았다. 보안상의 이유로 128bit 암호화 기술은 수출 금지 품목이었기 때문이다. 이에 정보통신부 산하 기관인 KISA(한국정보보호진흥원)에서는 시드(Seed)라는 128bit 대칭키 블록 암호화 알고리즘을 개발하였고 이를 브라우저에 탑재하기 위하여 액티브X 컨트롤을 사용하였다. 이는 곧 국내 표준이 되었다. 금융감독원은 이 기술을 전자상거래를 위한 보안성 심의 기준으로 삼았으며, 결국 액티브X 컨트롤의 확산에 단단히 한 몫을 하게 되었다.

 

국제 표준이 되어버린 SSL

 

하지만 2000년대 이후 128bit 암호화 기술을 사용하는 SSL (Secure Sockets Layer)이 로열티를 지불하지 않는 국제표준으로 인정되면서 대부분의 브라우저에서 이 기술을 채택하게 되었다. 하지만 우리나라는 이미 액티브X를 이용하여 자체적으로 구현하고 있는 암호화 기술이 있었다. 애써 만들고 구축한 시스템은 쉽사리 SSL로 대체되지 않았다.

 

윈도우 비스타와 IE7의 등장

 

하지만 액티브X 기술이 가지고 있는 보안상의 문제점은 지속적으로 제기되어 왔고, 마이크로소프트(이하 MS)도 보안에 취약한 액티브X 컨트롤로 인하여 상당한 이미지의 타격을 입게 되었다. 결국 새로운 운영체제(Vista)와 새 브라우저(IE7)를 출시하면서 극단의 처방으로 액티브X 컨트롤에 대한 보안을 강화하기에 까지 이른 것이다. MS의 입장에서도 태생적으로 보안에 취약한 액티브X 컨트롤을 그대로 방치해 두기에는 보안에 취약한 운영체제라는 오명을 벗을 수 있는 길이 없었던 탓이다.

 

액티브X 사태 확산과 해결 노력

 

올해 초 비스타 출시에 맞춰 금융감독원에서는 비스타 호환성 이슈를 해결하지 못한 사이트는 보안상의 문제로 인하여 금융 거래를 할 수 없도록 막았다. 그제야 액티브X 컨트롤 사태가 전국적으로 이슈가 되기 시작했고 각 사이트들은 액티브X 컨트롤 문제를 해결하기 위하여 부랴부랴 대응 방안을 마련하고 대응 컨트롤을 제작하게 된 것이다.

하지만 이런 노력들은 장기적인 대안이 되질 않는다. 결국 비스타와 IE7 보안 기준에 맞춘 또 다른 액티브X 컨트롤을 만들고 있기 때문이다. 우리나라 웹사이트는 금융 거래를 하는 사이트 몇 개만 들락날락 거려도 수십 개의 액티브X 컨트롤이 설치된다. 각자 서로 다른 액티브X 컨트롤을 구축해서 사용하기 때문에 사용자 입장에서는 상당히 불편한 점 중에 하나이다.

 

정부의 자각

 

정부도 이러한 액티브X 사태를 겪으면서 이러한 문제가 다시 나타나지 않게 하기 위한 방안들을 모색 중이다. 그 시작은 신규 발주 사업의 제안 요청서에 특정 업체의 제품(기술)만 지원하지 않도록 웹 표준을 준수해 다양한 운영체제와 여러 브라우저에서 작동할 수 있도록 구현할 것을 명시한 것이다. 즉 이제는 액티브X 컨트롤처럼 한 가지 OS나 한 가지 브라우저에서만 작동하는 웹 사이트는 안 만들겠다는 뜻이다.

문제의 근본 원인

 

그렇다면 이와 같은 문제점의 근본적인 원인은 무엇일까? 그것은 바로 브라우저가 가진 기능의 한계에 있다. 초기의 브라우저는 단순히 정보를 표현하는 도구로 출발을 하였다. HTML 태그를 이용하여 정보를 만들고 이를 서로 링크로 연결하여 정보의 네트워크를 만들어 표현하는 것이 주목적이었다. 그러다 보니 브라우저라는 것은 결국 정보를 표현하는 것이 주된 목적이었던 것이다. 여기에 128bit 암호화 기술이나, 키보드 보안 기술은 고려 대상이 아니었다. 하지만 웹이 가진 네트워크라는 속성은 서로를 연결시켜주는 폭발적인 힘으로 작용하면서 전 세계가 웹 하나로 급속하게 연결 되었다.

이러한 발전은 웹이 더 이상 단순히 정보만 보여주는 도구가 아니라, 사용자가 정보를 스스로 생산해 내고 참여하게 만드는 새로운 네트워크 질서의 패러다임(웹2.0)으로 바뀌어 갔다. 그러다 보니 브라우저는 이제 그 능력의 한계를 드러내고 이 능력을 확장하기 위하여 액티브X 컨트롤과 같은 기술이 나타났던 것이다.

 

급속한 IT 성장의 부작용

 

지금까지 살펴본 일련의 과정을 정리하면 액티브X 문제를 거론하며 정부와 MS만을 탓할 수만은 없다는 걸 알 수 있을 것이다. 우리나라는 너무 일찍 태동한 전자상거래 탓에 남들보다 빠른 보안 기술을 개발하여 사용하게 되었고, 시간이 지난 뒤에 오래된 기술이 취약점을 드러냈다고 볼 수도 있는 탓이다.

해외 여러 나라와 달리 유독 우리나라에서만 액티브X 컨트롤 사태가 이슈화 되는 이유도 바로 그런 배경 때문이다. 이제는 잘잘못을 가릴 때가 아니라 지난 날 우리의 과오를 인정하고 새로운 대안들을 찾으면 될 일이다.

 

 

액티브X의 대체 기술들

 

 

액티브X의 대체 기술에 대해 이야기 하려면 먼저 세 가지로 나누어 생각해 봐야한다. 흔히, 공인인증서 문제에 대해서만 많이 보도되고 있지만, 개발자들에게 산적된 문제는 인증서에만 국한되지 않기 때문이다.

 

비스타에서의 액티브X 호환성 확보하기

 

그 중에서 가장 먼저 알아봐야 할 것은 발등에 떨어진 불을 어떻게 하면 끌 수 있을 지에 대한 것으로 임시방편이라고도 할 수 있겠다. MS는 비스타에 설치된 IE7에서의 액티브X 컨트롤 문제를 해결하기 위해 몇 가지 방법을 내놓았다. 뒤에 좀 더 자세히 알아보겠지만 먼저 간단히 정리해 보면 액티브X 컨트롤의 권한을 상승시키는 방법과 보호 모드의 예외 정책을 이용하는 방법 그리고 브로커를 이용하여 관리자 권한이 필요한 액티브X가 실행되도록 하는 것이다.

 

플랫폼 독립적인 공인인증서 만들기

 

두 번째로 검토해 봐야 할 문제는 특정 운영체제와 브라우저에서만 동작하는 액티브X를 대체하면서도 여러 플랫폼(운영체제와 브라우저)에서 실행될 수 있는 공인인증서이다. 몇 차례 보도를 통해 알려진 것처럼 현재 이런 문제의 해결을 위해 가장 큰 관심을 받고 있는 분야는 자바 기술이다. 애초에 한 번 만들어서 어디에서나 실행되도록 한다는 WORA(Write Once, Run Anywhere)에 입각해 만들어진 자바이기에 보다 다양한 운영체제와 브라우저에서 실행되는 인증서 컨트롤을 만들 수 있기 때문이다. 물론, 기존 액티브X 공인인증서를 완전히 대체할 수 있으려면 아직 해결해야 할 문제들이 산적해 있지만, 이미 사설 인증서를 만든 국내 업체도 있고 자바를 통해 공인인증서 서비스를 하고 있는 해외 사례들도 있어 가장 현실적인 방법으로 꼽히고 있다.

 

액티브X 대체 기술 확보

 

바로 이 부분이 이번 특집을 통해 주로 다뤄질 내용들이다. 언론을 통해 결제나 공인인증서 문제만 다뤄지다 보니 액티브X가 마치 그런 일에만 사용되는 것처럼 느껴질 정도다. 하지만, 실제로 액티브X가 사용되는 분야는 훨씬 많다. 이런 액티브X 애플리케이션을 대체하는 애플리케이션을 만들기 위해 사용할 수 있는 기술들이 있다. 바로 XPCOM과 Ajax, 실버라이트다. 이 내용들은 각각 특집 3, 4, 5부에서 자세히 다뤄진다.

 

 

윈도우 비스타 IE7의 액티브X 개발 방법

 

 

윈도우 비스타가 기존 윈도우와 가장 다른 점은 보안이 상당히 강화되었다는 점이다. 문제는 이 보안 강화가 기존 액티브X 컨트롤의 사용에 제약이 된다는 점이다. 특히, 윈도우 비스타에 IE7을 설치하여 사용할 때 기본으로 제공되는 UAC(User Account Control)와 보호모드(Protected Mode)가 문제다. 보안 기능 탓에 몇몇 웹 사이트에서 기존에 제공하고 있던 액티브X 컨트롤의 사용이 어려워졌고, 아직도 이 문제를 해결하지 못한 사이트도 있을 정도다. 이번에는 UAC와 보호모드에 대해 알아보고, MS에서 권고하고 있는 방법들을 기반으로, 윈도우 비스타 환경의 IE7에서도 실행되는 액티브X 컨트롤 개발 방법에 대해 알아보자.

 

UAC란?

 

UAC란 User Account Control의 약자로 사용자 계정을 제어하는 기능이다. 그럼, 왜 이런 기능이 만들어졌고 대체 무엇 때문에 이 기능이 문제시 되는 것일까?

기존 윈도우의 사용자들은 윈도우를 설치하고 나면 관리자 권한으로 등록하여 모든 기능들을 자유롭게 사용하였다. 하지만, 이런 사용자 패턴이 보안에 치명적인 문제를 일으킬 수도 있기 때문에, 비스타에서는 사용자가 관리자 그룹에 속해 있더라도 자동으로 관리자 권한을 사용할 수 없도록 막고 있다. 대체 이게 무슨 소리일까? 윈도우XP와 비교하며 좀 더 자세히 살펴보자.

윈도우XP에도 나름의 보안 개념은 있었다. 그래서 일반 사용자 권한으로는 응용프로그램의 설치나 시스템의 시계 설정, 네트워크나 프린터 설정 등을 변경하지 못하도록 제한하고 있었다. 그러나 기자를 포함하여 보안 의식이 낮은 사용자들에게 애플리케이션을 설치하거나 설정을 변경할 때마다 관리자 권한으로 다시 로그인 하는 것은 무척 귀찮은 일이었다. 그래서 그냥 관리자 권한을 기본 계정으로 사용해 왔던 것이다. 관리자 권한으로 사용하고 있으니 여기에 그레이웨어나 해킹 프로그램 등이 접속하면 시스템을 통째로 들었다 놨다 할 수 있는 상황이 자주 벌어진 것이다.

비스타에서는 바로 이런 문제를 원천적으로 봉쇄하기 위해 기본적으로는 관리자 계정을 비활성화 시켜서 사용할 수 없도록 만들어 버린 것이다. 아무리 관리자 그룹에 속해있는 사용자라도 보통 때에는 표준 사용자 권한으로 사용해야 한다. 그리고 관리자 권한이 필요할 때에는 사용자의 동의를 얻거나 관리자 계정 정보를 입력하여 관리자 권한을 일시적으로 획득하여 사용하도록 만들어진 기능이다.

여기에 추가로 사용자가 생성한 프로세스는 시스템 영역의 데이터를 건드릴 수도 없고 오직 사용자 계정 폴더에만 데이터를 쓰거나 수정할 수 있다. 레지스트리 기록도 마찬가지다. HKEY_CURRENT_USER 이외의 시스템에는 접근이 제한된다. 적절한 사전 작업 없이는 Win32 API의 호출도 불가능하다.

 

권한 상승과 가상화

 

이러한 UAC 기능 탓에 기존에 만들어 둔 액티브X 컨트롤이 재 기능을 하지 못한다면 권한 상승(Elevation)이나 가상화(Virtualization)를 활용해 볼 수 있다. 그 밖에도 몇 가지 방법이 더 있지만 여기에서는 이 두 가지 방법에 대해서만 간단히 알아본다.

 

● 권한 상승

앞서도 이야기한 것처럼 윈도우 비스타에서는 기본적으로 표준 사용자 계정을 사용하도록 되어 있고, 관리자 권한이 필요한 경우 권한 상승 과정을 거쳐야 한다. 여기에서 말하는 권한 상승 과정이란 사용자가 관리자 권한을 가지고 있는지 인증하는 것을 말하는데, 상황에 따라 두 가지 창이 표시되어 인증을 하도록 되어있다. 그중 하나는 사용자가 관리자 그룹의 계정으로 사용하고 있는 경우인데, 이때에는 사용자 동의 창이 표시되어 관리자 권한이 필요한 프로그램을 실행시킬 것인지 묻는다. 만약, 사용자가 일반 사용자 그룹에 속한 계정을 사용하고 있다면 관리자 계정 정보 입력을 요구하는 창이 표시된다.

그런데, 권한이 상승되는 방법이 몇 가지 더 있다. 윈도우 비스타에서 권한이 상승되는 경우는 다음의 네 가지다.

  • 사용자가 직접 권한 상승할 때 (관리자 권한으로 실행)
  • 프로그램 호환성 탭에 관리자 권한으로 실행하도록 설정된 경우
  • 설치 프로그램을 실행할 때
  • 관리자 권한으로 마킹된 실행 파일을 실행할 때

여기에서 눈여겨봐야 할 부분은 마지막에 있는 관리자 권한으로 마킹된 실행 파일을 실행할 때 자동으로 권한이 상등된다는 부분이다. 애플리케이션의 매니페스트(manifast)에 높은 레벨(관리자 권한)을 설정하면 자동으로 권한 상승이 일어나기 때문이다.

이 방법을 사용하면 액티브X 컨트롤이 윈도우 비스타의 IE7에서 실행되도록 할 수 있다. 윈도우 XP에서의 매니페스트는 DLL이나 COM 객체들의 의존성을 정의하는 용도로 사용되었지만, 비스타에서는 애플리케이션의 실행 권한을 명시하는 용도가 추가되었다. 매니페스트에 마킹하여 권한을 상승시키는 방법과 예제는 http://www.microsoft.com/korea/windows/ie/ ie7/technology/default.mspx에 있는 ‘Windows Vista 상에서 ActiveX Control 개발 방법’을 참고하길 바란다.

 

● 가상화

MS에서 임시방편으로 제공해 주고 있는 UAC 해결 방법이 하나 더 있다. 바로 가상화를 이용하는 방법이다. 가상화는 다시 파일 가상화와 레지스트리 가상화로 나눠진다.

이중에서 파일 가상화는 애플리케이션이 파일을 시스템 폴더에 저장할 때 발생하는 문제를 해결하기 위해 사용되는 기술이며, 레지스트리 가상화는 HKEY_LOCAL_MACHINE\SOFTW ARE 아래의 레지스트리 키에 사용할 수 있다. 이 위치에 설정 정보를 저장해야 할 경우 레지스트리 가상화 기능을 이용하여 실제 키를 HKU\{SID}_Classes\VirtualStore\Machine\Software로 리디렉션하여 사용하는 것이다. 마찬가지로 파일 가상화도 시스템 폴더 대신 사용자별 가상 경로에 파일을 저장하도록 해 준다.

그런데 주의할 점은 이 기술이 계속 지원되지는 않는다는 점이다. 그렇기 때문에 기존에 만들어 놓은 액티브X의 호환성 문제를 일시적으로 해결하기 위한 용도로만 사용해야 한다.

 

IE7의 보호모드와 예외정책

 

윈도우 비스타에 설치된 IE7에서만 동작하는 보호모드는 모든 프로세스와 보안 객체에 저마다의 접근 수준을 지정하여 접근 수준이 낮은 객체가 그보다 높은 수준의 데이터를 기록하지 못하도록 한다. 접근 수준은 각각 높음과 보통, 낮음으로 나뉘는데 윈도우 비스타에서의 IE7은 기본적으로 ‘낮음’으로 실행되기 때문에 ‘높음’이나 ‘보통’ 수준의 시스템 자원에 접근하는 것이 불가능하다. 이 문제는 브로커를 이용하여 접근수준을 높이는 방법으로 해결할 수 있다. 참고 자료에 링크되어 있는 ‘Windows Vista 상에서 ActiveX Control 개발 방법’에는 이와 관련된 정보와 예제들이 자세히 설명되어 있으니 참고하길 바란다.


 

출처명 : 한국마이크로소프트 [2007년 6월호]
 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)