Apache 웹서버의 SSL 기능 추가를 위한 모듈인 mod_ssl 문서 중 2장 부분.
10년전 아르바이트로 번역한 것이지만 여전히 mod_ssl은 업데이트 중이다.

개인적으로 이 문서가 SSL (TLS)의 이해를 위한 기본적 암호 기술 지식과 SSL 자체의 구조를 가장 쉽고 간단하게 정리한 문서라 생각된다.

===============================================================

Chapter.2 Introduction

Cryptographic Techniques

SSL 이해하기 위해서는 암호화 알고리즘, 메시지 다이제스트(one-way or hash function), 전자서명에 대한 이해가 필요하다. technique들은 privacy, integrity, authentication 있어서의 basis 제공한다.

Cryptographic Algroithm

Alice 돈을 옮기기 위하여 자신의 은행에 메시지를 보낸다고 가정하자. 메시지에는 Alice 계좌번호, 송금액 등과 같은 정보가 포함되기 때문에 Alice 메시지가 private하기를 원한다. 이에 대한 해결책은 암호화 알고리즘을 사용하는 것이며, 암호화를 사용함으로써 Alice 메시지를 암호화된 형태로 전송하여 다른 사람들로 하여금 읽을 없도록 만든다.

메시지는 secret key 사용하여야만 해석되어질 있으며, key 없으면 메시지는 무용지물이 된다. 좋은 암호화 알고리즘은 공격자(intruder) 원래의 메시지로 decoding하는 것을 어렵게 만듦으로써 공격자의 수고를 가치 없게 만든다.

암호화 알고리즘에는 두가지 범주가 있다. : Conventional, Public key.

Conventional Cryptography

  • symmetric cryptography라고도 하며, 메시지의 송신자, 수신자가 동일한 key 공유하게 되며, key 메시지를 암호화하고 복호화하는데 사용되는 secret piece of information이다. key 안전하게 보관됨으로써 전송자와 수신자 이외에는 메시지를 읽지 못하게 된다. 만약 Alice 은행이 secret key 알고 있다면 그들은 서로에게 private message 전송할 있다. 그러나 통신 이전에 key private하게 공유하는 것이 문제가 있다.

Public Key Cryptography

  • asymmetric cryptography라고도 하며, 두개의 key 사용하는 알고리즘을 정의함으로써 key exchange 문제를 해결하며, 두개의 key 어느 것도 메시지를 암호화하는데 사용될 있다. 만약 하나의 키가 메시지를 암호화하는데 사용되었다면 다른 하나의 key 그것을 복호화하는데 사용되어져야 한다. 공개키 암호화는 단순히 하나의 (공개키) 공개하고 다른 하나의 (개인키) 보관함으로써 메시지를 안전하게 전달할 있게 해준다.
  • 누구나 공개키를 사용하여 메시지를 암호화할 있지만 해당되는 개인키를 가진 사람만이 메시지를 읽을 있다. 이러한 방식으로 Alice 은행의 공개키로 메시지를 암호화함으로써 키쌍의 주인인 은행으로 private message 보낼 있게 되며, 단지 은행만이 메시지를 복호화할 있다.

메시지 다이제스트

비록 Alice 자신의 메시지를 암호화함으로써 안전하게 만들 수는 있지만, 누군가가 돈을 가로채기 위하여 Alice original message 변조하거나 다른 message 바꿔치기 있다는 문제가 여전히 존재한다. Alice 메시지에 대한 무결성(integrity) 보장하는 하나의 방법은 Alice 메시지에 대한 간결한 요약(summary) 생성해서 메시지와 함께 은행으로 보내는 것이다. 메시지를 받게 되면 은행은 메시지의 summary 다시 생성해서 Alice 보낸 것과 비교하게 되며, 두개가 일치하면 메시지는 손상되지 않은 것이다.

이러한 summary 메시지 다이제스트, one-way function, 혹은 hash function이라고 부른다. Message digests are used to create short, fixed-length representations of longer, variable-length messages. 다이제스트 알고리즘은 서로 다른 메시지에 대하여 각각 유일한 다이제스트를 생성하도록 디자인되어진다. 또한 다이제스트로부터 원래의 메시지를 얻어내는 것이 매우 어렵게 되어 있으며, 동일한 다이제스트를 가지는 서로 다른 두개의 메시지를 찾는 것이 불가능하다. 따라서 어떤 메시지를 동일한 다이제스트를 가지는 다른 메시지로 바꿔치기할 가능성을 막아주게 된다.

Alice 직면하게 되는 다른 문제는 다이제스트를 은행으로 안전하게 보내는 방법이며, 문제가 해결되면 해당 메시지에 대한 무결성이 보장된다. 이를 위한 한가지 방법은 다이제스트를 전자 서명에 포함하는 것이다.

전자 서명(Digital Signatures)

Alice 은행으로 메시지를 전송하였을 은행은 공격자(intruder) Alice 계좌로부터 돈을 인출하는 것을 막기 위해 메시지가 정말로 Alice 보낸 것인가를 확인할 필요가 있다. 역할을 하는 것이 Alice 생성하여 메시지에 포함한 전자 서명이다.

전자 서명(Digital signatures) 메시지의 다이제스트와 다른 정보들(sequence number 같은) 전송자(sender) 개인키로 암호화함으로써 생성된다. 비록 누구나 전송자의 공개키를 가지고 서명을 복호화할 수는 있지만 단지 서명자만이 개인키를 알고 있을 뿐이며, 이것은 서명자만이 서명을 생성할 있음을 의미한다. 서명에 다이제스트를 포함한다는 것은 서명이 단지 메시지에 대해서만 유효함을 의미한다. 이것은 또한 누구도 다이제스트를 변경하지 못하며 서명을 없기 때문에 메시지의 무결성을 보장해준다.

Intruder 의한 가로채기(interception) 서명의 재사용을 막기 위하여 서명은 유일한 sequence number 포함하고 있으며, 이것은 은행으로 하여금 Alice 자신이 메시지를 보내지 않았다고 하는 부정하게(fraudulent) 클레임을 거는 것을 막아주게 된다. 이유는 단지 Alice만이 메시지에 서명할 있기 때문이다. 이를 부인봉쇄(non-repudiation)이라고 한다.

인증서(Certificates)

비록 Alice private message 은행으로 보내고, 메시지에 서명하고 또한 메시지의 무결성을 보장받을 있지만 여전히 Alice 자신이 정말로 은행과 통신(communicate)하고 있는가를 확인할 필요가 있다. 이것은 자신이 사용하는 공개키가 은행의 개인키와 대응되는가를 확인할 필요가 있음을 의미한다. 또한 은행 역시 메시지의 서명이 정말로 Alice 서명에 대응되는가를 확인할 필요가 있다.

만약 party 서로의 identity validate해주고 공개키를 confirm해주며, 또한 믿을 있는 agency 의해 서명된 증명서(certificate) 가진다면 그들은 자신이 생각하고 있는 올바른 상대방과 통신하고 있음을 확신할 있을 것이다. 이러한 믿을 있는 agency Certificate Authority라고 부르며, 증명서(certificate) 인증(authentication) 사용된다.

Certificate Contents

증명서는 하나의 공개키와 실재의 subject 보여지는 identity(individual, server 등등) 연관시킨다. subject 대한 정보는 identifying information(the distinguished name) 공개키를 포함한다. 또한 증명서는 증명서를 발급한 CA 대한 identification 서명, 그리고 증명서의 유효기간을 포함한다. 증명서에는 serial number 같이 CA 관리적 목적으로 사용하기 위한 administrative information 같은 부가적인 정보를 가질 수도 있다.

Subject:

Distinguished Name, Public Key

Issuer:

Distinguished Name, Signature

Period of Validity:

Not Before Date, Not After Date

Administrative Information:

Version, Serial Number

Extended Information:

Basic Contraints, Netscape Flags, etc.

Table 1: Certificate Information

Distinguished name 특정한 context 내에서 identity 제공하기 위해 사용된다. 예를 들어, 개인(individual) 개인 증명서(personal certificate) 뿐만 아니라 하나의 employee로서의 증명서을 가진다. Distinguished name X.509 표준[X509] 정의되어 있으며, 여기에는 field, field name, abbreviation(약어) 정의되어 있다.

A distinguished name is used to provide an identity in a specific context ? for instance, an individual might have a personal certificate as well as one for their identity as an employee. Distinguished names are defined by the X.509 standard [X509], which defines the fields, field names, and abbreviations used to refer to the fields (see Table 2).

DN Field:

Abbrev.:

Description:

Example:

Common Name

CN

Name being certified

CN=Joe Average

Organization or

Company

O

Name is associated with this organization

O=Snake Oil, Ltd.

Organizational Unit

OU

Name is associated with this organization unit, such as a department

OU=Research Institute

City/Locality

L

Name is located in this City

L=Snake City

State/Province

ST

Name is located in this State/Province

ST=Desert

Country

C

Name is located in this Country (ISO code)

C=XZ

Table 2: Distinguished Name Information

CA 어떤 DN name 필수적(required)이냐, 부가적(optional)이냐를 명시하는 정책(policy) 정의할 있으며, 또한 필드의 내용(field content) 대한 요구사항(requirement) 포함할 있다. 예를 들면, Netscape 브라우져는 어떤 서버에 대한 증명서의 Common Name 서버의 도메인 네임에 대한 wildcard pattern ( *.snakeoil.com 같은…) 부합(match)되는 이름을 가질 것을 요구한다.

증명서의 binary format ASN.1 notation [ X208] [PKCS] 사용하여 정의한다. notation content information binary form으로 변환하는 방법을 정의하는 encoding rule들을 어떻게 specify하는가를 정의한다. 증명서의 binary encoding Distinguished Encoding Rules(DER) 사용하여 정의하며, DER 일반적인 Basic Encoding Rules(BER) 기반을 두고 있다. Binary 다루지 못하는(cannot handle) transmission 위하여 binary form Base64 encoding [MIME] 사용하여 ASCII form으로 변환될 수도 있다. 이렇게 encoding 버전을 PEM(“Privacy Enhanced Mail”에서 얻어진 이름) encoded라고 부르며, [Table3]에서와 같이 begin delimiter line end delimiter line 사이에 놓여진다.

-----BEGIN CERTIFICATE-----

MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCWFkx

FTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25ha2UgVG93bjEXMBUG

A1UEChMOU25ha2UgT2lsLCBMdGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhv

cml0eTEVMBMGA1UEAxMMU25ha2UgT2lsIENBMR4wHAYJKoZIhvcNAQkBFg9jYUBz

bmFrZW9pbC5kb20wHhcNOTgxMDIxMDg1ODM2WhcNOTkxMDIxMDg1ODM2WjCBpzEL

MAkGA1UEBhMCWFkxFTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25h

a2UgVG93bjEXMBUGA1UEChMOU25ha2UgT2lsLCBMdGQxFzAVBgNVBAsTDldlYnNl

cnZlciBUZWFtMRkwFwYDVQQDExB3d3cuc25ha2VvaWwuZG9tMR8wHQYJKoZIhvcN

AQkBFhB3d3dAc25ha2VvaWwuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB

gQDH9Ge/s2zcH+da+rPTx/DPRp3xGjHZ4GG6pCmvADIEtBtKBFAcZ64n+Dy7Np8b

vKR+yy5DGQiijsH1D/j8HlGE+q4TZ8OFk7BNBFazHxFbYI4OKMiCxdKzdif1yfaa

lWoANFlAzlSdbxeGVHoT0K+gT5w3UxwZKv2DLbCTzLZyPwIDAQABoyYwJDAPBgNV

HRMECDAGAQH/AgEAMBEGCWCGSAGG+EIBAQQEAwIAQDANBgkqhkiG9w0BAQQFAAOB

gQAZUIHAL4D09oE6Lv2k56Gp38OBDuILvwLg1v1KL8mQR+KFjghCrtpqaztZqcDt

2q2QoyulCgSzHbEGmi0EsdkPfg6mp0penssIFePYNI+/8u9HT4LuKMJX15hxBam7

dUHzICxBVC1lnHyYGjDuAMhe396lYAn8bCld1/L4NMGBCQ==

-----END CERTIFICATE-----

Table 3: Example of a PEM-encoded certificate (snakeoil.crt)

인증기관(Certificate Authorities)

CA 증명서를 발급하기 전에 먼저 증명서에 있는 정보를 확인(verify)함으로써 키쌍의 개인키의 identity 확인(assure)한다. 예를 들어 만약 Alice 개인 증명서(personal certificate) 요청하는 경우 CA 반드시 먼저 Alice 정말로 증명서를 요청한 사람인가를 확인하여야 한다.

Certificate Chains

CA 다른 CA 대한 증명서을 발급(issue) 있다. 증명서를 examining Alice Alice 신뢰할 있는 CA 도달할 때까지 parent CA 대한 issuer 증명서를 examine해야 필요가 있을 있다. Alice chain안의 “bad” certificate 대한 위험을 줄이기 위하여 제한된 chain(limited chain of issuers) 가진 증명서만을 신뢰할 것을 결정할 수도 있다.

Creating a Root-Level CA

위에서 언급된 바와 같이, certificate들은 top-level CA 도달할 때까지 certificate subject identity 대한 유효성(validity) certificate issuer 보증해야 한다. 이것은 하나의 문제를 발생시키는데, 그것은 issuer 가지지 않는 top-level authority certificate 누가 보증하는가의 문제이다. 이런 특정한 경우, top-level authority certificate “self-signed”되어지며, 증명서의 issuer subject 동일하게 된다. 결과로서 self-signed certificate 신뢰에 대한 문제가 생긴다. Root authority 의한 공개키의 wide publication 공개키의 신뢰에 대한 위험을 줄여줄 있는데, 누군가가 자신이 authority 되겠다고 하면서 키를 공표함으로써 문제를 해결할 있다. 보통 브라우져들은 well-known CA들을 신뢰할 있도록 미리 설정되어있다(preconfigured).

Thawte이나 VeriSign 같은 몇몇 회사들이 자신을 Certificate Authority로서 입지를 굳혀왔으며, 이들은 다음과 같은 서비스를 제공한다:

  • 증명서 요청에 대한 확인(Verifying certificate requests)
  • 증명서 요청의 처리(Processing certificate requests)
  • 증명서의 발급과 관리(Issuing and managing certificates)

자기 자신만의 CA(one’s own CA) 생성하는 것도 가능한데, 비록 인터넷 환경에서는 위험하긴 하지만 어떤 조직 내에서 개인이나 서버들을 확인(verify)하기 위한 목적의 인트라넷 환경에서는 매우 유용할 있다.

Certificate Management

CA 설립(establishing)하는 것은 믿을 있는 관리적(administrative), 기술적(technical), 관리(management) framework 요구하는 일이다. CA 증명서를 발급할 뿐만 아니라 증명서를 관리해야 한다. , 증명서가 어느 기간 동안 유효한가를 결정하고, 증명서를 갱신하며, 발급은 되었지만 이상 유효하지 않은 증명서들의 리스트(Certificate Revocation Lists - CRL) 관리해야 한다. 만약 Alice에게 어떤 회사의 직원으로서의 증명서를 발급하였다면 Alice 회사를 떠날 증명서는 취소되어야 필요가 있다. 그러나 증명서는 돌아다니는 것이기 때문에 증명서 자체만으로는 그것이 취소되었다는 것을 알려줄 없다. 따라서 증명서의 유효성(validity) 확인하고자 CRL 체크하기 위해서 증명서를 발급한 CA 문의(contact) 필요가 있다(보통 이것은 자동으로 되는 프로세스가 아니다-- this is not usually an automated part of the process).

Note:

브라우져에 디폴트로 설정되어져 있지 않은 CA 사용하는 경우, 브라우져로 하여금 CA 서명한 server certificate 확인(validate) 있도록 하기 위해 CA certificate 브라우져에 load해야 하는데, 이것은 브라우져가 일단 한번 CA certificate load하면 CA 서명한 모든 certificate 받아들이게 되기 때문에 위험할 있다.

 

Secure Sockets Layer (SSL)

Secure Sockets Layer protocol Reliable connection-oriented network layer protocol (e.g. TCP/IP) Application protocol layer (e.g. HTTP) 사이에 위치하는 Protocol Layer이다. SSL 상호 인증, 무결성을 위한 전자 서명의 사용, privacy 위한 암호화 등을 이용하여 클라이언트와 서버간의 안전한 통신을 제공한다.

프로토콜은 암호화, 다이제스트, 서명을 위한 특정 알고리즘의 선택을 지원하도록 디자인되어졌다. 이것은 특정 서버의 알고리즘 선택이 법적인 문제나 수출법과 같은 문제에 기반하여 이루어질 있도록 해주며, 또한 프로토콜로 하여금 새로운 알고리즘의 채택을 가능하게 해준다. 알고리즘의 선택은 프로토콜 세션이 시작될 클라이언트와 서버 간에 협상(negotiation)된다.

Version:

Source:

Description:

Browser Support:

SSL v2.0

Vendor Standard

(from Netscape Corp.)

[SSL2]

First SSL protocol for which implementations exists

- NS Navigator 1.x/2.x

- MS IE 3.x

- Lynx/2.8+SSLeay

SSL v3.0

Expired Internet Draft

(from Netscape Corp.)

[SSL3]

Revisions to prvent specific security attacks, add non-RSA ciphers, and support for certificate chains

- NS Navigator 2.x/3.x/4.x

- MS IE 3.x/4.x

- Lynx/2.8+SSLeay

TLS v1.0

Proposed Internet Standard

(from IETF)

[TLS1]

Revision of SSL 3.0 to update the MAC layer to HMAC, add block padding for block ciphers, message order standardization and more alert messages.

- Lynx/2.8+SSLeay

Table 4: Versions of the SSL protocol

[Table 4] 보여지는 바와 같이 몇가지 버전의 SSL 프로토콜이 있다. 위에 기술된 바처럼, SSL 3.0 장점 하나는 certificate chain loading 지원한다는 것이며, 이것은 서버가 브라우져에게 issuer certificate 함께 서버의 certificate 넘겨주는 것을 가능하게 해준다. 또한 Chain loading 기능은 해당 서버 certificate 서명한 issuer CA certificate 브라우져에 설치되어 있지 않은 경우에도 server certificate certificate chain 포함되어 있기 때문에 브라우져가 server certificate 확인(validate) 있도록 해준다. Transport Layer Security [TLS] protocol standard SSL 3.0 기반으로 하였으며, 현재 Internet Engineering Task Force (IETF) 의해 개발되고 있다.

Session Establishment

SSL 세션은 [Figure 1]에서와 같이 클라이언트와 서버 간의 handshake sequence 따라 이루어진다. sequence 서버가 server certificate 제공하느냐, 혹은 client certificate 요구하는가에 따라 달라질 있다. Cipher information 관리를 위해 부가적인 handshake step 요구되는 경우도 존재하지만 여기서는 하나의 일반적인 시나리오를 정리한다: 가능한 모든 경우에 대한 설명은 SSL specification 참조하라

Note

일단 SSL 세션이 이루어지면 이것은 재사용되어질 있으며, 이로 인하여 세션을 시작하기 위해 필요한 많은 단계들을 반복함으로써 발생하는 performance penalty 피할 있다. Reusing 기능을 위하여 서버는 SSL 세션마다 유일한 session identifier 할당하며, identifier 서버에 저장되어서 이후에 클라이언트가 다시 연결할 이를 사용함으로써 handshake 줄일 있다(session identifier 서버의 캐쉬에서 지워지기 이전까지 사용할 있다).

Figure 1: Simplified SSL Handshake Sequence

Handshake sequence 요소는 다음과 같다.

  1. 데이터 전송 시에 사용할 Cipher Suite 협상(negotiation)한다.( Negotiate the Cipher Suite to be used during data transfer)
  2. 클라이언트와 서버 간의 세션키를 공유한다.( Establish and share a session key between client and server)
  3. 부가적으로(Optionally) 클라이언트에게 서버를 인증한다.(authenticate the server to the client)
  4. 부가적으로(Optionally) 서버에게 클라이언트를 인증한다.(authenticate the client to the server)

첫번째 단계인 Cipher Suite Negotiation에서 클라이언트와 서버는 양측 모두가 지원할 있는 Cipher Suite 선택한다. SSL 3.0 프로토콜 규격은 31개의 Cipher Suite 정의되어 있다. 하나의 Cipher Suite 다음의 요소들로 정의된다:

  • Key Exchange Method
  • Cipher for Data Transfer
  • Message Digest for creating the Message Authentication Code (MAC)

Key Exchange Method

Key exchange method 어플리케이션 데이터의 전송에 사용할 공유 비밀키를 어떻게 클라이언트와 서버간에 동의(agree) 것인가를 정의한다. SSL 2.0 RSA 교환만을 지원하지만 SSL 3.0 가지 교환 알고리즘(RSA key exchange, Diffie-Hellman key exchange) 중에 선택할 있도록 지원한다. RSA 교환은 certificate 사용되는 경우에 선택되며, Diffie-Hellman 교환은 certificate 없고 클라이언트와 서버 간의 통신이 이전에 한번도 없는 경우에 선택된다.

Key exchange method 선택에 있어서 하나의 변수는 전자 서명을 사용할 것인가 사용하지 않을 것인가, 그리고 사용한다면 어떤 종류의 서명을 사용할 것인가이다. 개인키를 이용한 서명을 사용함으로써 공유키를 생성하는데 사용되는 정보를 교환할 man-in-the-middle-attack 막을 있다 [AC96, p516].

Cipher for Data Transfer

SSL 세션 내의 메시지를 암호화하기 위해서 위에서 기술된 conventional cryptography algorithm(대칭형 암호화) 사용한다. 암호화를 하지 않는 경우를 포함해서 9가지의 선택이 가능하다:

No encryption

Stream Ciphers

    • RC4 with 40-bit keys
    • RC4 with 128-bit keys

CBC Block Ciphers

    • RC2 with 40 bit key
    • DES with 40 bit key
    • DES with 54 bit key
    • Triple-DES with 168 bit key
    • Idea (128 bit key)
    • Fortezza (96 bit key)

“CBC” Cipher Block Chaining 의미하며, 모드에서는 바로 이전에 암호화된 암호문의 일부가 현재 block 암호화에 사용되어진다. “DES” Data Encryption Standard 의미하며, 여러가지의 variant(DES40, 3DES_EDE) 있다. "Idea" 암호학적으로 가장 강력한 알고리즘이며, "RC2" RSA DSI에서 개발한 독점적인 알고리즘이다.

Digest Function

Digest Function 선택은 record unit으로부터 어떻게 다이제스트가 생성되어지는가를 결정하며, SSL 다음을 지원한다:

  • No digest (Null choice)
  • MD5, a 128-bit hash
  • Secure Hash Algorithm (SHA-1), a 160-bit hash

메시지 다이제스트는 Message Authentication Code (MAC) 생성하는데 사용된다. MAC 메시지와 함께 암호화됨으로써 메시지의 무결성을 제공하며 또한 replay attack 막아준다.

Handshake Sequence Protocol

Handshake sequence 가지의 프로토콜을 사용한다:

  • The SSL Handshake Protocol for performing the client and server SSL session establishment.
  • The SSL Change Cipher Spec Protocol for actually establishing agreement on the Cipher Suite for the session.
  • The SSL Alert Protocol for conveying SSL error messages between client and server.

These protocols, as well as application protocol data, are encapsulated in the SSL Record Protocol, as shown in Figure 2. An encapsulated protocol is transferred as data by the lower layer protocol, which does not examine the data. The encapsulated protocol has no knowledge of the underlying protocol.

Figure 2: SSL Protocol Stack

The encapsulation of SSL control protocols by the record protocol means that if an active session is renegotiated the control protocols will be transmitted securely. If there were no session before, then the Null cipher suite is used, which means there is no encryption and messages have no integrity digests until the session has been established.

Data Transfer

SSL Record Protocol application data SSL Control data 작은 unit 쪼개거나, multiple higher level protocol data message 하나의 unit 결합하여 클라이언트와 서버 간에 전송한다. It may compress, attach digest signatures, and encrypt these units before transmitting them using the underlying reliable transport protocol (Note: currently all major SSL implementations lack support for compression).

Figure 3: SSL Record Protocol

Securing HTTP Communication

SSL 보통 브라우져와 서버 간의 HTTP 통신을 안전하게 만드는데 사용되며, 경우 non-secure HTTP 사용하지 않는 것이 아니라, SSL 위에서 일반적인 plain HTTP 구현한다(HTTPS라고 한다). 한가지 중요한 차이는 HTTPS 이용할 http 다른 서버 포트(디폴트 443) 사용하는 것이 아니라 https라는 URL scheme 사용한다는 것이며, 이것이 mod_ssl Apche 웹서버에 제공하는 주요한 기능이다.

References

[AC96] Bruce Schneier, Applied Cryptography, 2nd Edition, Wiley, 1996. See

http://www.counterpane.com/ for various other materials by Bruce Schneier.

[X208] ITU-T Recommendation X.208, Specification of Abstract Syntax Notation One (ASN.1), 1988.

See for instance ftp://ftp.neda.com/pub/itu/x.series/x208.ps.

[X509] ITU-T Recommendation X.509, The Directory ? Authentication Framework, 1988.

See for instance ftp://ftp.bull.com/pub/OSIdirectory/ITUnov96/X.509/97x509final.doc.

[PKCS] Kaliski, Burton S., Jr., An Overview of the PKCS Standards, An RSA Laboratories Technical Note, revised November 1, 1993. See http://www.rsa.com/rsalabs/pubs/PKCS/.

[MIME] N. Freed, N. Borenstein, ultipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies, RFC2045. See for instance ftp://ftp.isi.edu/in-notes/rfc2045.txt.

[SSL2] Kipp E.B. Hickman, The SSL Protocol, 1995.

See http://www.netscape.com/eng/security/SSL_2.html.

[SSL3] Alan O. Freier, Philip Karlton, Paul C. Kocher, The SSL Protocol Version 3.0, 1996. See

http://www.netscape.com/eng/ssl3/draft302.txt.

[TLS1] Tim Dierks, Christopher Allen, The TLS Protocol Version 1.0, 1997. See

ftp://ftp.ietf.org/internet-drafts/draft-ietf-tls-protocol-06.txt.

Posted by Golmong
:


테스트 용도 및 내부 어플리케이션 사용 용도라면 굳이 돈주고 Verisign 인증서 같은걸 사서 쓸 필요 없이 간단히 OpenSSL로 만들어 사용하는 것도 좋은 방법이지요.

인증서란 것이 발급한 기관이 어디냐에 따라서 브라우저 같은 Application에서 그냥 넘어가느냐 못믿을 놈이니 확인해라 라는 컴플레인을 하거나의 차이일 뿐 표준에 따라 만드는 것이라 다를 것이 없으니까요....

OpenSSL로 인증서 생성 및 변환하는 것을 아주 간략히 정리해봅니다.
OpenSSL을 설치하면 openssl 이라는 이름의 실행파일이 있으며 이는 OpenSSL 패키지에 대한 데모 및 샘플 코드 제공, 각종 암호키에 대한 변환 등의 기능을 제공하는 툴입니다.
이 툴로 사실 우리가 필요로 하는 거의 대부분의 키 핸들링이 가능하다고 볼 수 있습니다.


1. Demo CA 설정
- 현재 디렉토리에 demoCA 디렉토리 생성 : mkdir demoCA
- demoCA 디렉토리 안에 시리얼 파일 생성 : serial 이란 이름의 text 파일에 00 을 적는다.
- index 파일 생성 :  index.txt 란 이름으로 빈 파일을 만든다.

2. CA 인증서 생성
- CA 개인키 생성 :  openssl genrsa -des3 -out ca.key 1024
- Self-Signed CA 인증서 생성 :  openssl req -new -x509 -days 365 -key ca.key -out ca.crt

3. 하위 인증서 생성 (예: HTTPS Web 서버용..)
- server 개인키 생성 : openssl genrsa -des3 -out server.key 1024
- server 인증서 발급을 위한 요청파일 생성 : openssl req -new -days 365 -key server.key -out server.csr
- server 인증서 발급 : openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt -outdir .

위 작업의 결과로 server.crt 라는 server용인증서가 생성되고 index 파일에 발급내역이, serial이 16진수로 1씩 증가한다.

4. 인증서 인코딩 포멧 변경
- openssl 이 생성하는 인증서의 인코딩은 발급 시 옵션을 주지 않으면 디폴트가 PEM (base64 encoding)이다.
- Java 등에서 사용하기 위한 DER 포맷(바이너리)으로 변경은 다음과 같이 수행한다.
   : openssl x509 -in ca.crt -out ca.der -outform DER

5. 인증서 내용 보기
- openssl x509 -in ca.crt -text   (PEM 포맷인 경우)
- openssl x509 -in ca.der -inform DER -text (DER 포맷인 경우)
Posted by Golmong
:


오랫동안 JavaME(Micro Edition)에 대한 최대의 관심은 2000년 5월에 최종적인 형태로 공개된 바 있는 CLDC(Connected Limited Device Configuration)에 집중되어 왔으며, 2개월 후에 최초의 CLDC 기반 프로파일인 MIDP(Mobile Information Device Profile)가 발표되었다. MIDP는 새로운 애플리케이션 모델과 더불어 사용자 인터페이스 및 persistence를 위한 클래스를 정의한다는 이유로 자바 커뮤니티에서 커다란 반향을 불러일으켰었다. 다시 말해서 MIDP는 인터랙티브 애플리케이션의 배치 및 실행을 위한 완벽한 환경을 제공했던 것이다.

JavaME의의 또 다른 구성인 CDC(Connected Device Configuration)는 거의 1년 뒤인 2001년 3월에 가서야 JCP(Java Community Process)를 통해서 마무리되었고, 이와 동시에 최초의 CDC 기반 프로파일인 Foundation Profile(FP)이 발표되었다. 하지만 FP는 MIDP와 달리 인터랙티브 애플리케이션 구축을 위한 클래스를 제공하지 않았으며, 결국 CDC/FP 조합은 자바 커뮤니티에서 그다지 큰 관심을 끌지는 못했다.

한편, 두 가지의 새로운 CDC 기반 프로파일이 완결되었는데, 이 두 프로파일--Personal Basis Profile(PBP)과 Personal Profile(PP)--은 더 이상 활발한 개발이 이루어지지 않고 있는 PersonalJava 플랫폼을 대체하고 있다. 이 프로파일들은 PersonalJava와 마찬가지로 인터랙티브 애플리케이션 구축에 필요한 클래스를 제공한다. 본 기사에서는 먼저 이 두 프로파일에 대해 살펴보고, 두 프로파일의 차이점을 비롯하여 프로파일과 PersonalJava 플랫폼을 비교 분석해보기로 한다.

공통 기반

새로운 프로파일을 제대로 이해하려면, 반드시 Connected Device Configuration과 Foundation Profile이 JavaME 플랫폼에 대해 어떤 역할을 하는지 이해해야만 한다. 왜냐하면, PBP와 PP 모두 CDC/FP 조합에 기반을 두고 있기 때문이다.

CDC 요약

CDC가 정의하는 자바 런타임 환경(JSR 36)은 CLDC가 정의하는 환경보다 Java SE에 훨씬 가깝다고 할 수 있다. 일례로, CDC 기반 장치는 Java 2 Platform 언어 스펙과 Java 2 Platform 가상 머신 스펙을 완벽하게 지원한다. 또한 이들은 Java SE 1.3 애플리케이션 프로그래밍 인터페이스(API)의 서브세트이며, 클래스는 다음 패키지에 속해있다.

  • java.io
  • java.lang
  • java.lang.ref
  • java.lang.reflect
  • java.lang.math
  • java.net
  • java.security
  • java.security.cert
  • java.text
  • java.util
  • java.util.jar
  • java.util.zip

단, 일반적으로 CDC는 각 패키지 내 클래스의 일부만을 포함한다는 점에 유의할 것. 예를 들어, java.net 패키지에서는 데이터그램과 URL 처리와 관련한 클래스만 포함되며, 스트림 기반 소켓 지원은 CDC에 포함되지 않는다.

CDC는 CLDC의 수퍼세트이므로 마찬가지로 javax.microedition.io 패키지 내의 GCF(Generic Connection Framework)를 구성하는 클래스를 포함한다. CDC 기반 장치는 java.iojava.net 패키지의 API 외에도 GCF를 이용하여 파일을 읽고 쓰고, 데이터그램을 주고 받을 수 있다.

Foundation Profile 요약

Foundation Profile(JSR 46)은 주로 CDC에서 생략된 JavaSE API를 추가하는데, 특히 다음의 패키지를 예로 들 수 있다.

  • java.io
  • java.lang
  • java.net
  • java.security
  • java.security.cert
  • java.text
  • java.util
  • java.util.jar
  • java.util.zip

FP는 또한 CDC에서 볼 수 없는 다음 세 가지 패키지의 클래스를 포함한다.

  • java.security.acl
  • java.security.interfaces
  • ava.security.spec

FP에는 스트림 기반 소켓과 HTTP 연결에 필요한 java.net 클래스가 포함된다는 점에 유의할 것. 이 연결은 또한 GCF를 통해서도 이용이 가능하다--실제로, FP에는 MIDP의 javax.microedition.io.HttpConnection 인터페이스가 포함된다.

여러분도 알다시피, CDC/FP 연결은 범용 프로그램을 위한 강력한 환경을 정의하지만 정작 인터랙티브 애플리케이션 구축에 필요한 클래스는 빠져 있다.

Personal Basis Profile

Personal Basis Profile(JSR 129)은 Foundation Profile의 슈퍼세트로, 다음 세 가지의 새로운 기능을 제공한다.

  • Java TV API를 기반으로 한 Xlet 애플리케이션 모델
  • 경량형 컴포넌트에만 기반을 둔 사용자 인터페이스를 구축하기 위한 JavaSE AWT(Abstract Windowing Toolkit)의 일부분
  • RMI(Remote Method Invocation) API의 일부분을 이용하는 IXC(Inter-Xlet Communication)

이 기능들을 이용하면 효과적으로 정의된 라이프사이클을 갖춘 양방향 애플리케이션을 개발할 수 있다.

포함된 패키지

PBP는 새로운 기능을 지원하기 위해 CDC/FP에 이미 포함된 것 외에도 다음과 같은 JavaSE 1.3 패키지의 일부를 포함하고 있다.

  • java.awt
  • java.awt.color
  • java.awt.event
  • java.awt.image
  • java.beans
  • java.rmi
  • java.rmi.registry

단, PBP는 RMI를 지원하지 않는다는 점에 유의할 것. java.rmijava.rmi.registry 패키지는 정식 RMI라기보다는 Xlet 간 통신(IXC)을 지원하기 위해 포함되었다. PBP 기반 디바이스는 RMI 지원이 가능하지만, 이는 모든 CDC 기반 디바이스에 포함될 수 있는 별도의 스펙인 RMIOP(RMI Optional Package)를 구현하는 경우에만 가능하다.

Xlet 애플리케이션 모델

전통적인 자바 애플리케이션 모델은 상당히 단순하다고 할 수 있다. 즉, 클래스를 로드하고 main() 메소드를 인보크한 다음 모든 비(非) Background 스레드가 종료되거나 System.exit()가 호출될 때까지 기다린다. 대부분의 애플리케이션의 경우, 이 모델은 애플리케이션 동작에 대한 통제권을 거의 허용하지 않는다. 이런 이유 때문에 MIDP는 디바이스가 외부 이벤트에 반응하여 애플리케이션을 시작, 종료, 일시 중지할 수 있게 해주는 MIDlet 애플리케이션 모델을 정의하며, 브라우저 기반 애플리케이션--애플릿--은 다른 애플리케이션 모델을 이용한다.

PBP는 여러 가지 면에서 MIDlet 모델과 유사한 자체 애플리케이션 모델을 정의한다. Xlet 모델은 Java TV API에서 차용된 것으로, 셋톱 박스 애플리케이션의 라이프사이클을 제어하는 데 사용된다. 이 모델의 두 가지 주요 요소로는 javax.microedition.xlet 패키지에 포함된 XletXletContext 인터페이스를 들 수 있다. 이 애플리케이션의 메인 클래스는 Xlet 인터페이스를 구현하며, 이 인터페이스는 시스템이 인보크할 이벤트 메소드를 정의한다. XletContext 인터페이스는 애플리케이션이 운영 환경에 관한 정보를 입수하는 데 사용하는 콜백 메소드를 정의한다. 다음은 흔히 볼 수 있는 Xlet의 예이다.

// Example of a trivial Xlet import javax.microedition.xlet.*; public class TrivialXlet implements Xlet { private XletContext context; public TrivialXlet(){ } public void destroyXlet( boolean unconditional ) throws XletStateChangeException { } public void initXlet( XletContext context ) throws XletStateChangeException { this.context = context; } public void pauseXlet(){ } public void startXlet() throws XletStateChangeException { context.notifyDestroyed(); // immediately quit } }

Xlet과 PBP에 관한 자세한 내용은 다음 기사를 참조하도록 한다.

PBP는 Xlet 모델뿐 아니라 종래의 애플리케이션 모델까지 지원한다는 점에 유의할 것.

AWT 서브세트

MIDP와 달리 PBP는 전혀 새로운 사용자 인터페이스 클래스 세트를 정의하지 않는 대신 표준 AWT 클래스를 서브세트로 취한다. JavaSE 애플리케이션 개발 경험이 많은 개발자들에게는 MIDP보다 PBP가(곧 살펴볼 Personal Profile과 함께) 훨씬 더 익숙한 환경으로 느껴질 것이다.

PBP의 AWT 서브세트에 포함된 클래스는 경량형 사용자 인터페이스 컴포넌트를 정의하고 사용하는 데 필요한 요소들이다. 원래 AWT는 중량형 컴포넌트로 구성되어 있었는데, 각 컴포넌트 인스턴스는 기본 운영체제에 있어서 고유한 UI 컴포넌트(이른바 피어 컴포넌트)를 위한 프록시에 지나지 않았다. 중량형 컴포넌트로 구축된 애플리케이션은 해당 플랫폼 상에서 실행되는 다른 애플리케이션과 유사한 외관과 분위기를 지니지만, 사용자 인터페이스 동작이나 외관에 대한 자바 런타임의 통제력이 제한되어 있다. 따라서 Java 1.1에는 외관과 분위기가 런타임에 의해 완벽히 통제되는 경량형 컴포넌트의 개념이 도입되었다. 이 경량형 모델에서는 각 컴포넌트가 상위의 추출 영역(drawing area)에서 자신을 직접 추출하고 상위에서 위임한 이벤트에만 반응하기 때문에, 최상위 윈도우를 제외하면 피어 컴포넌트는 아예 존재하지 않는다. 하지만, 런타임 시스템이 운영체제와 상호 작용할 방법이 필요하기 때문에 최상위 윈도우에는 대개 중량형 컴포넌트가 사용된다.

경량형 컴포넌트를 지원하기 위해 PBP에는 특히 다음과 같은 클래스가 포함되어 있다.

  • java.awt.Component - 모든 사용자 인터페이스 컴포넌트를 위한 기본 클래스
  • java.awt.Container - 타 컴포넌트를 포함하고 관리하는 AWT 컴포넌트를 위한 기본 클래스
  • java.awt.Window - 최상위 윈도우를 위한 기본 클래스
  • java.awt.Frame - 제목 표시줄과 테두리가 있는 최상위 윈도우

이들은 완벽한 사용자 인터페이스를 구축하는 데 필요한 핵심 컴포넌트 클래스들로서, 경량형 컴포넌트를 생성하는 데는 Component와 Container가, 그리고 이 경량형 컴포넌트를 담는 최상위 윈도우를 생성하는 데는 Window와 Frame이 사용된다. PBP의 다른 모든 AWT 클래스들은 이 네 가지 요소를 지원하는 데 사용된다.

PBP는 특히 Window와 Frame을 제외한 모든 중량 컴포넌트를 배제한다는 점에 유의할 것. 버튼이나 리스트, 메뉴를 비롯한 그 밖의 기본적인 사용자 인터페이스 컴포넌트는 포함되어 있지 않다. JavaSE의 경우에는 이 기본 컴포넌트의 경량형 버전이 Swing 사용자 인터페이스 툴키트에 의해 정의되지만 PBP에는 Swing이 포함되어 있지 않다.

중량형 컴포넌트가 빠져 있고 Swing을 이용할 수도 없다면 어떻게 사용자 인터페이스를 생성해야 할까? 다음과 같은 두 가지 방법이 가능하다.

각자의 애플리케이션이 아주 단순하다면 다음과 같이 자체 컴포넌트를 직접 작성할 수 있다.

import java.awt.*; /** * A _very_ simple UI component that draws a * centered text string. */ public class SimpleTextLabel extends Component { private String text; public SimpleTextLabel( String text ){ this.text = text; } public void paint( Graphics g ){ int h = getHeight(); int w = getWidth(); g.setColor( getBackground() ); g.fillRect( 0, 0, w, h ); g.setColor( getForeground() ); FontMetrics fm = g.getFontMetrics(); int textWidth = fm.stringWidth( text ); int textHeight = fm.getHeight(); int x = ( w - textWidth ) / 2; int y = ( h - 2 * textHeight ) / 2; g.drawString( text, x, y ); } }

런타임 시, 이 컴포넌트들을 직접 Frame 컴포넌트 상에 배치한다.

... Frame frame = ... // some frame you created SimpleTextLabel label; // Now build our user interface label = new SimpleTextLabel( "Press a key to exit" ); label.setBackground( Color.blue ); label.setForeground( Color.yellow ); label.addKeyListener( new KeyAdapter(){ public void keyTyped( KeyEvent e ){ exit(); } } ); frame.add( label );

새로운 Xlet 모델에 따라 실행되는 애플리케이션은 자체 프레임을 생성하는 대신 시스템이 공급하는 루트 컨테이너를(초기화 시 각 Xlet으로 전달되는 XletContext 오브젝트를 통해) 이용한다.

사용자 인터페이스를 작성하는 두 번째 방법은 제3의 경량형 사용자 인터페이스 툴키트를 사용하는 것인데, 이 툴키트에 벤더가 제공하는 클래스를 추가할 수도 있다.

PBP AWT 서브세트에는 중량 컴포넌트가 없다는 점 외에도, 애플리케이션의 사용자 인터페이스가 수행할 수 있는 기능에 뚜렷한 제약이 있기 때문에, UI 기능이 상대적으로 제한된 시스템 상에서만 PBP 애플리케이션의 운영이 가능하다. 가장 중요한 제약 사항은 애플리케이션이 Frame 클래스에서 하나의 인스턴스만을 사용할 수 있다는 점이다. 한편, 전통적인 모델을 이용하여 구축된 PBP 애플리케이션은 프레임을 스스로 생성하는 반면, 이와 대조적으로 Xlet 모델에서는 시스템이 애플리케이션을 대신해서 프레임을 생성하고, XletContext.getContainer() 메소드를 통해 이 프레임(또는 자식 컨테이너)을 이용할 수 있도록 한다. 그 밖의 프레임 기능은 옵션으로 제공되며, 시스템은 임의로 프레임의 크기와 상태, 위치를 제한할 수 있으며 프레임의 제목을 숨길 수도 있다. 그 밖에 커서 사용을 비롯한 몇 가지 세부사항에 대해서도 제약이 따른다.

Inter-Xlet Communication

IXC(Inter-Xlet Communication)는 동일한 가상 머신에서 운영되는 두 개 이상의 Xlet이 오브젝트를 교환하고 클래스 로더의 경계를 넘어 코드를 실행할 수 있게 해준다. IXC는 JavaSE의 RMI(Remote Method Invocation) 기능에 기반을 두고 있지만, 사실상 RMI는 VM 의 통신이 아닌 VM 에서의 통신을 위해 개발되었다. 그렇다고 해서 Xlet 간 통신 자체가 RMI 기능을 모두 이용할 수 있다는 것을 의미하지는 않는다는 사실을 기억하는 것이 중요하다. 또한, PBP 애플리케이션에서 RMI를 실행하려면 반드시 RMIOP를 사용해야 한다.

Xlet은 IXC 레지스트리를 이용하여 다른 Xlet이 오브젝트를 사용하도록 할 수 있는데, 이것을 오브젝트 바인딩 또는 익스포팅이라고 한다. 모든 Xlet은 동일한 레지스트리, 즉 javax.microedition.xlet.ixc.IxcRegistry 클래스의 싱글턴 인스턴스를 공유하는데, getRegistry() 팩토리 메소드는 아래와 같이 싱글턴을 반환한다.

... import javax.microedition.xlet.*; import javax.microedition.xlet.ixc.*; XletContext context = ..... // get the Xlet's context IxcRegistry registry = IxcRegistry.getRegistry( context ); ...

이 레지스트리는 공유 해시 테이블과 유사하다. Xlet은 bind() 메소드를 이용하여 오브젝트에 이름을 바인딩하는데, 원격 인터페이스를 구현하는 오브젝트만 레지스트리에 바인딩될 수 있다. 원격 인터페이스는 java.rmi.Remote를 확장하여 각 메소드가 java.rmi.RemoteException을 throw하도록 하는 인터페이스이며, 모든 메소드 파라미터와 반환 타입은 기본 타입이거가 직렬화가 가능한 오브젝트 또는 기타 원격 인터페이스이다.

다른 Xlet들은 lookup() 메소드를 이용하여 바인딩된 오브젝트를 찾아내며 이는 실제 오브젝트의 스텁(stub)을 반환하는데, 이 스텁은 런타임 시스템에 의해 자동으로 생성된다(이와 달리 RMI에서는 반드시 rmic 툴을 이용하여 수동으로 스텁을 생성해야 한다). 스텁은 원래의 오브젝트와 동일한 원격 인터페이스를 구현하며 이 오브젝트를 위한 프록시 역할을 한다. 애플리케이션이 스텁의 특정 메소드를 인보크할 경우, 시스템은 심지어 다른 쓰레드 상에 위치한 경우라도 원래의 오브젝트 상에서 동일한 메소드를 인보크한다. 이 때, 메소드 인수는 대부분 사용자가 예상한 대로 처리된다. 즉, 기본 타입이 복사되며, 직렬화가 가능한 오브젝트는 콜러(caller)에서 직렬화되고 콜리(callee)에서 직렬화 해제되며, 원격 오브젝트를 위해 스텁이 반환된다(실제 오브젝트에 대한 레퍼런스를 얻는 오브젝트를 바인딩한 Xlet에서는 예외).

다음은 IXC를 이용하여 애플리케이션 인스턴스가 동시에 2개 이상 실행되지 않도록 하는 예제 애플리케이션이다.

import java.rmi.*; import javax.microedition.xlet.*; import javax.microedition.xlet.ixc.*; /** * An Xlet that uses inter-Xlet communication (IXC) * to ensure that only once instance of the Xlet is * ever running. */ public class RunOnceXlet extends BasicXlet { private static final String NAME = "RunOnceXlet.activator"; private boolean removeBinding = false; public RunOnceXlet(){ } // The first thing the Xlet does is check to see if an // instance of itself is already running. public void initXlet( XletContext context ) throws XletStateChangeException { try { // Get the IXC registry and create an instance of // our own remote interface in case we're the first // instance running IxcRegistry registry = IxcRegistry.getRegistry( context ); RemoteInterface remote = new RemoteInterfaceImpl(); while( true ){ try { // First we try to bind our remote interface // to the registry. If two instances are // started simultaneously, only // one of them will win. registry.bind( NAME, remote ); removeBinding = true; break; } catch( AlreadyBoundException abe ){ try { // Somebody else has bound an interface, // so we get it and call its // activateAgain method before // terminating. remote = (RemoteInterface) registry.lookup( NAME ); String[] args = (String[]) context.getXletProperty( XletContext.ARGS ); remote.activateAgain( args ); throw new XletStateChangeException( "Already running" ); } catch( NotBoundException nbe ){ // Whoops, no object was found, the other // instance might have just terminated // so try to register ourselves again.... } } } } catch( RemoteException e ){ // If we can't connect, just start up... System.out.println( "Error dealing with registry:" ); e.printStackTrace(); } ..... // perform normal initialization } // Deregister the instance from the IXC registry. This // will happen automatically when the Xlet is destroyed, // but it's better to do it explicitly. public void exit(){ if( removeBinding ){ try { IxcRegistry registry = IxcRegistry.getRegistry( getContext() ); registry.unbind( NAME ); } catch( NotBoundException e ){ } catch( RemoteException e ){ } } ..... // do other cleanup stuff } /** * The remote interface instances of RunOnceXlet use to * communicate with each other. */ public interface RemoteInterface extends Remote { void activateAgain( String[] args ) throws RemoteException; } /** * The implementation of the remote interface. One difference * between IXC and regular RMI is that in regular RMI this * class would extend java.rmi.server.UnicastRemoteObject * and you would have to run rmic to generate the appropriate * stub classes. With IXC the stubs are generated * automatically. */ private class RemoteInterfaceImpl implements RemoteInterface { public RemoteInterfaceImpl() throws RemoteException { } // Our activation method. All it does is print out a // message, but it could easily do other // things by invoking methods on its containing class. // methods on its containing class. public void activateAgain( String[] args ) throws RemoteException { System.out.println( "[RemoteInterfaceImpl] Activation request" ); } } }

이 때, 클래스들은 IXC를 이용해 원격 로딩되지 않는다는 점에 유의할 것. 스텁은 자동으로 생성되지만, 이 스텁이 구현하는 실제 인터페이스는 반드시 애플리케이션과 함께 사전에 패키징되어 있어야 한다.

Personal Profile

Personal Profile(JSR 62)은 Personal Basis Profile의 슈퍼세트로, 다음과 같은 기능이 추가되었다.

  • 브라우저 기반 애플리케이션 구축을 위한 애플릿 지원
  • 중량형 컴포넌트, JDK 1.02 형 이벤트, deprecated API 등에 대한 지원을 포함하는 보다 포괄적인 AWT 서브세트
  • java.awt.datatransfer 패키지의 서브세트를 이용한 클립보드 지원

이와 같이 PP는 Xlet 애플리케이션 모델 및 Xlet 간 통신과 같은 새로운 PBP 기능을 제공하는 것은 물론, 보다 풍부하고 JavaSE에 가까운 환경을 제공한다.

포함된 패키지

PP는 PBP 클래스에 다음과 같은 세 가지의 JavaSE 1.3 패키지 클래스가 추가되어 있다.

  • java.applet
  • java.awt
  • java.awt.datatransfer

PP는 PBP와는 달리 비 JavaSE 클래스를 더 이상 정의하지 않는다.

애플릿 지원

애플릿 모델은 PBP가 지원하는 전통적인 애플리케이션 모델과 Xlet 애플리케이션 모델의 또 다른 대안이라 할 수 있다. 애플릿은 웹 브라우저에 의해 작성된 통제 환경(종종 sandbox로 불림) 내에서 실행되는 브라우저 기반 애플리케이션이다. MIDlet 및 Xlet과 마찬가지로, 애플릿은 사용자가 브라우저를 이용해 특정 웹 페이지에서 다른 웹 페이지로 이동하는 것과 같은 이벤트에 반응해 언제 시작 혹은 일시 중지, 종료할 것인지에 대해 시스템의 지시를 받게 된다. PP에서의 애플릿 지원은 본질적으로 Java 1.1 버전과 동일하기 때문에 대부분의 독자들에게 상당히 익숙한 방법일 것이다.

AWT 서브세트

PP의 AWT 서브세트는 PBP AWT 서브세트와는 달리 java.awt.Buttonjava.awt.List 클래스와 같은 표준 중량형 UI 컴포넌트를 지원한다. 이들 클래스는 애플릿 모델을 정상적으로 지원하는 데 필요한데, 이는 java.applet.Applet 클래스가 java.awt.Panel을 직접 확장하며, 많은 애플릿들이 표준 컴포넌트를 이용해 사용자 인터페이스를 작성하기 때문이다. 또한 AWT 서브세트는 애플릿 모델 지원을 위해 java.awt.Event 클래스와 Component.handleEvent() 메소드를 기반으로 하는 오리지널 Java 1.0.2 이벤트 모델도 지원한다. 한편, PP는 기존 애플릿과의 역호환을 위해 Component.enable() 등 PBP에서 제외된 deprecated AWT 메소드를 다시 도입하고 있다.

PP는 JavaSE 1.3의 AWT 클래스 대부분을 포함하고 있으며, 제외된 클래스로는 2차원 그래픽 클래스(java.awt.Paintjava.awt.Stroke), 프린팅 클래스(java.awt.PrintJob), 액세스 가능 클래스(java.awt.Component.AccessibleAWTComponent), java.awt.Robot class 등이 있다.

Personal Profile은 Personal Basis Profile에 적용된 사용자 인터페이스 제약 사항들을 다소 완화시켰는데, 특히 애플리케이션이 생성하는 프레임이나 대화상자의 수를 제한하지 않는다. 그러나 시스템은 전과 마찬가지로 최상위 윈도우의 크기나 상태, 위치 등을 임의로 제한할 수 있다. 즉, 이들 제약 사항들은 지나치게 UI 기능이 제한되는 시스템들을 지원하기 위한 것이다.

PersonalJava에서 마이그레이트하기

PersonalJava 스펙에 따라 작성된 애플리케이션의 경우, Personal Profile(일부의 경우 Personal Basis Profile)에 대한 JavaME 마이그레이션 수단을 제공한다. 물론 이 두 개의 Java 환경은 서로 이질적인 특성을 띠기 때문에 마이그레이션이 그리 간단하지는 않을 것이지만 숙련된 Java 프로그래머들이라면 작업이 그다지 어렵지 않을 뿐 아니라, 마이그레이션이 완료되는 순간부터 과거의(이제는 상당히 낡은) Java 1.1 API 대신 보다 친숙한 JavaSE 1.3 API를 사용하는 애플리케이션을 보유할 수 있게 될 것이다.

PersonalJava 1.2a 스펙이 정의하는 아래 패키지들은 Personal Profile에 포함된 같은 이름의 패키지들과 동일하거나 그 서브세트이다.

  • java.applet
  • java.awt.datatransfer
  • java.awt.event
  • java.awt.image
  • java.io
  • java.lang
  • java.reflect
  • java.net
  • java.security
  • java.security.cert
  • java.security.interfaces
  • java.security.spec
  • java.text
  • java.util
  • java.util.jar
  • java.util.zip

이 리스트에는 java.awt가 포함되어 있지 않다는 점에 유의할 것. PersonalJava에는 이 패키지의 PrintGraphicsPrintJob 클래스가 포함되어 있지만 Personal Profile은 그렇지 않다. 하지만 이 두 가지만 제외하면, PersonalJava java.awt 패키지는 Personal Profile java.awt 패키지의 서브세트와 동일하다.

PersonalJava 애플리케이션이 위에 나열된 패키지들(프린터 클래스가 없는 java.awt 포함) 만을 사용하도록 제한한다면, 이 애플리케이션은 별다른 수정 사항 없이 그대로 실행이 가능할 것이다. 프로그래머가 곤란을 겪을 수 있는 유일한 요소가 바로 deprecated 메소드인데, 왜냐하면 Personal Profile에는 AWT 클래스의 deprecated 메소드만 포함되어 있고, Java 1.1.8의 deprecated 메소드는 제외되어 있기 때문이다.

PersonalJava에 포함된 다른 패키지들이 Personal Profile에도 모두 포함되어 있는 것은 아니다. 특히,

  • java.beans 패키지에서 디자인 타임 클래스가 제외되어 있다.
  • PP는 RMI Optional Package가 없을 경우 RMI를 지원하지 않는다. (PersonalJava에서는 RMI가 옵션으로 제공된다는 점에 유의할 것).
  • CDC/Foundation Profile (JSR 169)의 JDBC Optional Package가 없을 경우, PP는 java.sql 패키지의 JDBC 클래스를 단 한 개도 포함하지 않는다. (PersonalJava에서는 JDBC가 옵션으로 제공된다는 점에 유의할 것).
  • PP는 com.sun.awt.com, com.sun.lang, com.sun.util 패키지에서 PersonalJava별 API를 지원하지 않는다. 따라서 이들을 이용하는 코드의 경우, Personal Profile의 가장 비슷한 API를 이용할 수 있도록 재작성되어야 한다.

PersonalJava에서 Personal Profile로의 마이그레이션이 쉽지 않은 이유가 바로 여기에 있다. 하지만 이러한 변경 작업 중 일부는 매우 간단하게 수행할 수 있는데, 한 예로 Personal Profile에 메소드가 존재하지 않을 경우에는 com.sun.lang.UnsupportedOperationException이 throw되는 경우를 들 수 있다. 반면에, com.sun.util.PTimer 사용을 java.util.Timer 사용으로 대체하는 것과 같은 작업은 이보다 훨씬 어려운 과정을 거쳐야 한다.

결론

이제까지 살펴본 것과 같이, Personal Basis Profile과 Personal Profile 모두 JavaSE 구현을 100% 지원하기에는 지나치게 많은 제약을 받는 디바이스를 위해 유저 인터렉티브한 Java 애플리케이션을 개발할 수 있는 완벽한 환경을 제공한다. 또한 이들 프로파일은 PersonalJava 애플리케이션을 Java 2 Platform으로 마이그레이트할 수 있는 수단을 제공하기도 한다.

이들 프로파일에 관한 자세한 내용은 Personal Profile section of the Wireless Java portal을 참조할 것.


Posted by Golmong
: