<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>오늘은 어디로 갈까...</title>
		<link>http://blog.kangwoo.kr/</link>
		<description>잠시 빌려쓰고, 낡아지면 버려지는 이 한몸. 빈손으로 태어나 결국 빈손으로 털고 돌아가는, 이 인생의 고갯길은, 그 어떤것도 내 것이 될 수 없고, 누구의 것도 될 수 없는, 구름과 바람같은 덧없는 인생살이인데, 하물며 이 마음은 오죽하랴. 그냥 잠시 허허 웃고 살다가리</description>
		<language>ko</language>
		<pubDate>Wed, 17 Feb 2010 12:43:54 +0900</pubDate>
		<generator>Tistory 1.1 (http://www.tistory.com/)</generator>
		<image>
		<title>오늘은 어디로 갈까...</title>
		<url><![CDATA[http://cfile22.uf.tistory.com/image/1439960F49B70257137E87]]></url>
		<link>http://blog.kangwoo.kr/</link>
		<description>잠시 빌려쓰고, 낡아지면 버려지는 이 한몸. 빈손으로 태어나 결국 빈손으로 털고 돌아가는, 이 인생의 고갯길은, 그 어떤것도 내 것이 될 수 없고, 누구의 것도 될 수 없는, 구름과 바람같은 덧없는 인생살이인데, 하물며 이 마음은 오죽하랴. 그냥 잠시 허허 웃고 살다가리</description>
		</image>
		<item>
			<title>네트워크 보안에 대한 단상</title>
			<link>http://blog.kangwoo.kr/134</link>
			<description>&lt;br /&gt;
&amp;nbsp;가져다 쓰면 편할것을... 생각해내서 만들어 쓰는것은 머리를 아프게 한다. 하지만, 이게 재미있으니... 어쩔수 없지.&lt;br /&gt;
&amp;nbsp;Client &amp;lt;-&amp;gt; Server 간에 안전한 통신을 하기 위해서는 어떻게 해야할까?&lt;br /&gt;
&amp;nbsp;아주 간단히 생각한다면&amp;nbsp;대칭키 암호화 알고리즘을 사용해서 데이터를 교류하면 될것이다. 그런데 대칭키 암호화를 사용할려면 동일한 비밀키를 C/S 두군데 가지고 있어야한다. 문제는 누군가가 이 비밀키를 알게 될 경우(만든 사람은 안다~~ ㅋㅋㅋ), 또는&amp;nbsp;클라이언트가 해킹당해서 비밀키가 누출되면... 모든 데이터에 빵꾸~~가 난다는 것이다. 거기다 꼬리가 길면 밟힌다고, 동일한 비밀키를 오래쓰면, 암호해독법에의한 공격에 취약해지기 마련이라서, 대칭키 암호화에 사용되는 비밀키는 단기간의 세션(SessionKey) 형태로 사용하는게 바람직할것 같다.&lt;br /&gt;
&amp;nbsp;그렇다면, 이 비밀키를 생성한후 C/S간에 공유하기 위한 키 교환 메커니즘이 필요하게 되는데, 만만한게 비대칭키 암호화 알고리즘이다. 수신자의 공개키로 암호화하여 보내면, 송신자의 개인키로 복호화한 후 사용하면 되는것이다.&lt;br /&gt;
&amp;nbsp;그럼, 누가 수신자 역할을 해야하는가? 서버? 클라이언트? 아니면 둘다?&lt;br /&gt;
&amp;nbsp;첫째, 서버가 수신자 역할을 한다고 가정하면, 클라이언트가 송신자 역할을 한다. 즉 클라이언트가 개인키를 가지게 되는데, 문제는 클라이언트는 해킹당하기 쉬워서 개인키가 누출될 수 있다는 위험성이 도사린다.&lt;br /&gt;
&amp;nbsp;둘째, 클라이언트가 수신자 역할을 한다고 가정하면, 서버가 송신자 역할을 한다. 서버가 개인키를 가지게 되는데, 서버가 해킹당할경우 볼장다본경우라서 논의할게 없고, 클라이언트가 대칭키 암호화에 사용할 비밀키(세션키)를 암호화해서&amp;nbsp; 서버에게 주면, 서버를 그 비밀키를 복호화해서, 해당 비밀키로 데이터를 교류하면 된다. 이럴 경우 문제가 없을까? 데이터 자체는 암호화되어서 제3자가 알아 볼수는 없지만, 데이터를 그대로 재사용할가 있다는것이다. 간단히 예를 들면, 로그인을 할 경우 사용자의 아이디와 비밀번호를 포함한 데이터가 암호화되어서 &quot;0b8b61c936ad65943a4d01e777c&quot;란 데이터가 서버로 날아간다고 하자, 제 3자는 그 사용자의 아이디와 비밀번호는 알 수 없지만, 동일한 데이터 즉, &quot;0b8b61c936ad65943a4d01e777c&quot;을 서버에 날리면 로그인을 할 수 있다는 것이다. 물론 받아오는 데이터도 암호화되어 있다면 알아볼 수 없겠지만, 뭔가 찜찜한것은 사실일것이다.(쓸데없는 생각인가..? -_-;)&lt;br /&gt;
&amp;nbsp;그렇다면 어떻게 해야하는것일까? 대칭키 암호화에 사용할 비밀키를 서버에서 만들어서 클라이언트에 넘겨주면 되는것이다.&lt;br /&gt;
&amp;nbsp;흠..&lt;br /&gt;
&amp;nbsp;일단 클라이언트에서 비밀키를 암호화해서 서버에 넘겨주면, 서버는&amp;nbsp;새로운 비밀키를 생성한후, 복호화한 비밀키를 가지고 암호화한후 클라이언트에게 넘겨준다. 그럼 넘겨받은 데이터를 자신의 비밀키를 가지고 복호화하면, 상호 통신에 사용할 비밀키를 획득하게된다. 음 뭔가 이상한것 같기도하고..&lt;br /&gt;
&amp;nbsp;다시 원점으로 돌아가보자.&lt;br /&gt;
&amp;nbsp;이전에 말한 첫번째 방법, 즉 클라이언트가 개인키를 가지는 방법인데, 개인키의 누출의 위험이 있으므로 각 클라인언트별로 실행시 키를 랜덤하게 생성하게 하면 될거 같다. 이럴 경우 발생할 수 있는 또다른 문제는 서버가 진짜 서버인지 판단할수 있는지 여부인데, 이건 두번째 방법, 즉 서버가 개인키를 가지게 하고, 클라이언트가 그 공개키를 가지게 하여 인증하면 될거 같다.&lt;br /&gt;
아 머리가 아프다... 뭔가 좀 더 멋드러진 방법이 없는것일까...?&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=5272200&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>낙서</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/134</guid>
			<comments>http://blog.kangwoo.kr/134#entry134comment</comments>
			<pubDate>Wed, 30 Dec 2009 10:26:05 +0900</pubDate>
		</item>
		<item>
			<title>PKCS #8 개인 키 정보 구문 표준에 관한 단상</title>
			<link>http://blog.kangwoo.kr/133</link>
			<description>&lt;P&gt;1. 잡설&lt;br /&gt;
&amp;nbsp;서버와 클라이언트간의 데이터를 암호화하기 위해서 RSA와 AES를 사용하기도 했다. 문제는 클라어언트의 JAVA가 나이가 연로(年老)하셔서 RSAPrivateKey를 지원안하는줄 알고 한번 구현해보고자 하는 그릇된 욕망으로 인해 삽질을 시작하게되었다. 1.3에서는 있는거 같은데, STB(셋탑)의 JAVA께서는 지원을 하시는지 확실히는 몰겄다. 언제나 느끼는 것이지만, 만들기 전에 찾아보는 현명한 습관을 하루 빨리 체득해야하는데 말이다.. --; 단지 지적 욕구를 충족하고자 하시는분만 이 글을 읽으시고, 절대로 현실세계에서는 사용하지 말기 바란다.&lt;br /&gt;
&lt;br /&gt;2. RSA용 키 생성&lt;br /&gt;
&amp;nbsp;일단 RSA에 사용하기 위한 키를 생성해보자.&lt;br /&gt;
&lt;PRE class=brush:java&gt;package kr.kangwoo.moon.sample;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import kr.kangwoo.util.ByteUtils;

public class KeyGen {

	public static void main(String[] args) throws Exception {
		
		// 1. 키 생성 완료
		KeyPairGenerator gen = KeyPairGenerator.getInstance(&quot;RSA&quot;);
//		gen.initialize(1024); // 1024 bits
		KeyPair keyPair = gen.generateKeyPair();
		
		PublicKey pubKey = keyPair.getPublic();
		PrivateKey priKey = keyPair.getPrivate();
		
		byte[] pubBytes = pubKey.getEncoded();
		byte[] priBytes = priKey.getEncoded();
		
		// 2. 키 불러오기
		KeyFactory keyFactory = KeyFactory.getInstance(&quot;RSA&quot;);
		
		PKCS8EncodedKeySpec priSpec = new PKCS8EncodedKeySpec(priBytes);
		PrivateKey privateKey = keyFactory.generatePrivate(priSpec);

		System.out.println(priKey);
		System.out.println(privateKey);
		System.out.println(priKey.equals(privateKey));
		
		X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubBytes);
		PublicKey publicKey = keyFactory.generatePublic(pubSpec);
		
		System.out.println(pubKey);
		System.out.println(publicKey);
		System.out.println(pubKey.equals(publicKey));
		
		
		System.out.println(&quot;개인키입니다.&quot;);
		System.out.println(ByteUtils.toHexString(privateKey.getEncoded()));
	}
}

&lt;/PRE&gt;&amp;nbsp; 실행결과&lt;br /&gt;
&lt;PRE&gt;Sun RSA private CRT key, 1024 bits
  modulus:          98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
  public exponent:  65537
  private exponent: 95424982464164318408735053611818737525775743847171323579913328769092776032507444130876449121730133676301508234676167032006717758161793725366568706522148356314255952502618174670664289187298920132480956331892827405186415397044362320128949328957015105859759408000615566939338475899541162627898412351669762844673
  prime p:          12008250515849944108488102843499187655464462509731422296877150117470960033720378393817005998217639840722804588451011564705219732141220363017738196616705489
  prime q:          8180665372814122660173069738611390116430652686953417350545079644723331346304424811054335466600885913977520264222372188538563562437033369510447765531902401
  prime exponent p: 6589265682759291545683341539251381455754962857240359013081100333010218116982044460357464786424504691274753171641596012785588476849147301445655141778384161
  prime exponent q: 3658125630036325719502448719955832564080087700747010831668738332060697749893914483616252730277638015091096767677813133913837126520586842957004168892044673
  crt coefficient:  2931067481768796750197829654251952834275144311709208657122584273794219248528207319954346442077549609036355755736257063586611921256982012960072866836025831
Sun RSA private CRT key, 1024 bits
  modulus:          98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
  public exponent:  65537
  private exponent: 95424982464164318408735053611818737525775743847171323579913328769092776032507444130876449121730133676301508234676167032006717758161793725366568706522148356314255952502618174670664289187298920132480956331892827405186415397044362320128949328957015105859759408000615566939338475899541162627898412351669762844673
  prime p:          12008250515849944108488102843499187655464462509731422296877150117470960033720378393817005998217639840722804588451011564705219732141220363017738196616705489
  prime q:          8180665372814122660173069738611390116430652686953417350545079644723331346304424811054335466600885913977520264222372188538563562437033369510447765531902401
  prime exponent p: 6589265682759291545683341539251381455754962857240359013081100333010218116982044460357464786424504691274753171641596012785588476849147301445655141778384161
  prime exponent q: 3658125630036325719502448719955832564080087700747010831668738332060697749893914483616252730277638015091096767677813133913837126520586842957004168892044673
  crt coefficient:  2931067481768796750197829654251952834275144311709208657122584273794219248528207319954346442077549609036355755736257063586611921256982012960072866836025831
true
Sun RSA public key, 1024 bits
  modulus: 98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
  public exponent: 65537
Sun RSA public key, 1024 bits
  modulus: 98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
  public exponent: 65537
true
개인키입니다.
30820276020100300d06092a864886f70d0101010500048202603082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7
&lt;/PRE&gt;&amp;nbsp;소스의 1번을 통해 생성한 키를 파일로 저장해서 재 사용할 예정이다. 문제는 바이트배열로 저장한 데이터를 다시 키로 만드는 방법인데, 소스의 2번을 이용하면 아주 손쉽게 사용할 수 있다. 그러나~~ 무덤파길 좋아하는 본인은 이 PKCS8EncodedKeySpec 를 직접 구현해보기로 했다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
3. PKCS #8이란?&lt;br /&gt;
&amp;nbsp;PKCS#8 : Private&amp;shy;Key Information Syntax Standard PKCS#8은 비밀키 정보를 위한 구문을 정의한다. &lt;br /&gt;
&amp;nbsp;비밀키 정보는 어떤 공개키 알고리즘에 대한 비밀키와 그것에 대한 속성들로 구성된다. 또한, 본 표준은 암호화된 비밀키에 대한 구문 설명도 포함한다. (출처:모름 --;) &lt;br /&gt;
&amp;nbsp;고 한다... 즉 비밀키를 저정하는 구문이라고 하는데, 이놈의 속살을 볼려면... 당연히 RFC를 뒤져주자.&lt;br /&gt;
&amp;nbsp;RFC5208(&lt;A href=&quot;http://www.ietf.org/rfc/rfc5208.txt&quot;&gt;http://www.ietf.org/rfc/rfc5208.txt&lt;/A&gt;)에 가면 상세한 설명이 나오는거 같다. 2페이지쯤 보면,&lt;br /&gt;
&lt;PRE&gt;5.  Private-Key Information Syntax

   This section gives the syntax for private-key information.

   Private-key information shall have ASN.1 type PrivateKeyInfo:

      PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL }

      Version ::= INTEGER

      PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier

      PrivateKey ::= OCTET STRING

      Attributes ::= SET OF Attribute

   The fields of type PrivateKeyInfo have the following meanings:

      version is the syntax version number, for compatibility with
      future revisions of this document.  It shall be 0 for this version
      of the document.

      privateKeyAlgorithm identifies the private-key algorithm.  One
      example of a private-key algorithm is PKCS #1&#039;s rsaEncryption
      [PKCS#1].

      privateKey is an octet string whose contents are the value of the
      private key.  The interpretation of the contents is defined in the
      registration of the private-key algorithm.  For an RSA private
      key, for example, the contents are a BER encoding of a value of
      type RSAPrivateKey.

      attributes is a set of attributes.  These are the extended
      information that is encrypted along with the private-key
      information.
&lt;/PRE&gt;이렇게 친절하게 설명을 해주신다. 까막눈이라서 정확한 뜻은 모르겠지만, 개인키정보는는 버전과, 개인키알고리즘, 개인키, 기타등등으로 이루어진다고 한다. &lt;br /&gt;
&lt;PRE&gt;      PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL }

      Version ::= INTEGER

      PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier

      PrivateKey ::= OCTET STRING

      Attributes ::= SET OF Attribute
&lt;/PRE&gt;저 놈이 ASN.1(Abstract Syntax Notation One)이라는 것인데, 복잡한 데이터 구조를 내부 구현에 독립적으로 추상화하여 표현하기 위한 표준 구문법이라고 한다. 저 구문법에 따로 표현된 타입에 할당된 값을 부호화하여 방법을 제공하는게&amp;nbsp;BER(Basic Encoding Rules)라고 하고, DER(Distinguished Encoding Rules)은 유일한 Octet 문자열로 부호화하는 BER의 부분집이라고 하는데, 뭔소리인지... 본인도 잘 모르겠다. Octect은&amp;nbsp;8비트의 집합으로 흔히 알고 있는 바이트와 비슷하다고 보면 된다.(8비는 1바이트라고 알고 있지만, 컴에 따라 달라질수도 있단다. 그래서 저런 용어를 사용한다고 한다.)&lt;br /&gt;
&amp;nbsp;그럼 저 추상화 같은 놈을 어떻게 하면 실체화시킬수 있는것일까? 조금전 설명한 BER을 이용하면 된다. 간단히 설명하면 BER format은&amp;nbsp;타입(Type)과 값의 길이(Length), 값(Value)으로 이루어진 TLV로 만들어진다.&amp;nbsp;타입은 octect으로 구성되어 있는데 8,7 비트는 class를, 6비트는&amp;nbsp;primitive/construected,&amp;nbsp;5-1비티는 숫자를 나타난다. 자세한 설명은 위키(&lt;A href=&quot;http://en.wikipedia.org/wiki/Basic_Encoding_Rules&quot;&gt;http://en.wikipedia.org/wiki/Basic_Encoding_Rules&lt;/A&gt;)와 &lt;A href=&quot;http://www.vijaymukhi.com/vmis/ber.htm&quot;&gt;http://www.vijaymukhi.com/vmis/ber.htm&lt;/A&gt;를 참조하기 바란다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;자, 저 글들을 바탕으로 한 번 구현해보자.&lt;br /&gt;
&amp;nbsp;테스트용 데이터는 조금전 생성한 &quot;30820276020100300d06092a864886f70d0101010500048202603082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7&quot;을 사용하겠다.&lt;br /&gt;
&amp;nbsp;1바이트씩 읽어보겠다.&lt;br /&gt;
&amp;nbsp;처음 0x30은 2진수 00110000 로서 Type을 나타낸다. Class가 00이므로 Universal을 나타내고, P/C가 1이니&amp;nbsp;constructed, 숫자가 10000 즉 16을 나타내므로 SEQUENCE가 된다.&lt;br /&gt;
&amp;nbsp;두번째 0x82는 길이를 나타낸다. 만약 길이가 1바이트만으로 표현된다면 255자 이상의 데이터는 나타낼 수가 없을것이다. 그래서 길이 데이터의 8번째 비트가 1을 나타내면 7-1비트는 길이의 길이를 나타내게 된다. 즉 7-1비티의 값이 2이면, 다음 바이트부터 2바이트가 길이 값으로 쓰인다는것이다. 0x82abcd이면 0x82는 길이의 길이값이 2바이트고, 길이는 0xabcd (43981)이 된다는 것이다. 여기서는 0x820276이므로, 630의 값을 나타낸다.&lt;br /&gt;
&amp;nbsp;다섯번째 0x02부터 630개의 바이트들은 데이터로 사용된다. 이로서 SEQUENCE 구문이 끝났다.&lt;br /&gt;
&amp;nbsp;다시 데이터의 0x02부터 분석해보면, ASN.1에 나타난데로 INTEGER라 것을 알수 있고, 값을 0이다. 이런식으로 계속 분석해보면 아래와 같은 값들을 얻을 수 있다. (OID 계산하는방법은 생략하겠다.)&lt;br /&gt;
&lt;PRE class=brush:java&gt;package kr.kangwoo.moon.sample;

import java.io.IOException;
import java.math.BigInteger;

import kr.kangwoo.bada.server.KeyGen;
import kr.kangwoo.util.ByteUtils;

public class PKCS8EncodedKeySpec {
	
    public static final int BOOLEAN             = 0x01;
    public static final int INTEGER             = 0x02;
    public static final int BIT_STRING          = 0x03;
    public static final int OCTET_STRING        = 0x04;
    public static final int NULL                = 0x05;
    public static final int OBJECT_IDENTIFIER   = 0x06;
    public static final int EXTERNAL            = 0x08;
    public static final int ENUMERATED          = 0x0a;
    public static final int SEQUENCE            = 0x10;
    public static final int SEQUENCE_OF         = 0x10; // for completeness
    public static final int SET                 = 0x11;
    public static final int SET_OF              = 0x11; // for completeness
    
    public static final int CONSTRUCTED         = 0x20;
    public static final int APPLICATION         = 0x40;
    public static final int TAGGED              = 0x80;
    
	private byte[] bytes;
	private int index = 0;
	
	public PKCS8EncodedKeySpec(byte[] bytes) {
		this.bytes = bytes;
	}
	
	public void readObject() throws IOException {
		while (index &amp;lt; bytes.length) {
			byte type = read();
			int length = readLength();

			if (length &amp;gt;= 0) {
				if (type == 0 || length == 0) {
					return;
				}
				byte[] value = new byte[length];
				readFully(value);
				
				if (type == (CONSTRUCTED | SEQUENCE)) {
					System.out.println(&quot;SEQUENCE Length=&quot; + length);

					PKCS8EncodedKeySpec k = new PKCS8EncodedKeySpec(value);
					k.readObject();
				} else if (type == INTEGER) {
					System.out.println(&quot;INTEGER &quot; + new BigInteger(value));
				} else if (type == OCTET_STRING) {
					System.out.println(&quot;OCTET_STRING &quot; + ByteUtils.toHexString(value));
				} else if (type == NULL) {
					System.out.println(&quot;NULL &quot;);
				} else if (type == OBJECT_IDENTIFIER) {
					System.out.println(&quot;OBJECT_IDENTIFIER &quot; + getObjectIdentifier(value));
				}
			} else {
				// 뭘 처리 할까요?
			}
		}

	}
	
	public byte read() {
//		System.out.println(&quot;[&quot; + bytes.length + &quot;-&quot; + index + &quot;] &quot; + ByteUtils.toHexString(bytes[index]) + &quot; &quot; + ByteUtils.toBinaryString(bytes[index]));
		return bytes[index++];
	}
	
	public void readFully(byte[] bytes) {
		for (int i = 0; i &amp;lt; bytes.length; i++) {
			bytes[i] = read();
		}
	}
	
	private int readLength() throws IOException {
		int length = read() &amp;amp; 0xff;
		if (length &amp;lt; 0) {
			
		}
		
		if (length == 0x80) {
			return -1;
		}
		
		if (length &amp;gt; 127) {
			int size = length &amp;amp; 0x7f;
			if (size &amp;gt; 4) {
				throw new IOException(&quot;DER length more than 4 bytes&quot;);
			}
			
			length = 0;
			for (int i = 0; i &amp;lt; size; i++) {
				int next = read() &amp;amp; 0xff;

				if (next &amp;lt; 0) {
					throw new IOException(&quot;EOF found reading length&quot;);
				}

				length = (length &amp;lt;&amp;lt; 8) + next;
			}
            
			if (length &amp;lt; 0) {
				throw new IOException(&quot;corrupted stream - negative length found&quot;);
			}
		}
		return length;
	}
	
	public String getObjectIdentifier(byte[] bytes) {
		StringBuffer objId = new StringBuffer();
		long value = 0;
		BigInteger bigValue = null;
		boolean first = true;

		for (int i = 0; i != bytes.length; i++) {
			int b = bytes[i] &amp;amp; 0xff;

			if (value &amp;lt; 0x80000000000000L) {
				value = value * 128 + (b &amp;amp; 0x7f);
				if ((b &amp;amp; 0x80) == 0) { // end of number reached
					if (first) {
						switch ((int) value / 40) {
						case 0:
							objId.append(&#039;0&#039;);
							break;
						case 1:
							objId.append(&#039;1&#039;);
							value -= 40;
							break;
						default:
							objId.append(&#039;2&#039;);
							value -= 80;
						}
						first = false;
					}

					objId.append(&#039;.&#039;);
					objId.append(value);
					value = 0;
				}
			} else {
				if (bigValue == null) {
					bigValue = BigInteger.valueOf(value);
				}
				bigValue = bigValue.shiftLeft(7);
				bigValue = bigValue.or(BigInteger.valueOf(b &amp;amp; 0x7f));
				if ((b &amp;amp; 0x80) == 0) {
					objId.append(&#039;.&#039;);
					objId.append(bigValue);
					bigValue = null;
					value = 0;
				}
			}
		}

		return objId.toString();
	}

	public static void main(String[] args) throws Exception {
//		Sun RSA private CRT key, 1024 bits
//		  modulus:          98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
//		  public exponent:  65537
//		  private exponent: 95424982464164318408735053611818737525775743847171323579913328769092776032507444130876449121730133676301508234676167032006717758161793725366568706522148356314255952502618174670664289187298920132480956331892827405186415397044362320128949328957015105859759408000615566939338475899541162627898412351669762844673
//		  prime p:          12008250515849944108488102843499187655464462509731422296877150117470960033720378393817005998217639840722804588451011564705219732141220363017738196616705489
//		  prime q:          8180665372814122660173069738611390116430652686953417350545079644723331346304424811054335466600885913977520264222372188538563562437033369510447765531902401
//		  prime exponent p: 6589265682759291545683341539251381455754962857240359013081100333010218116982044460357464786424504691274753171641596012785588476849147301445655141778384161
//		  prime exponent q: 3658125630036325719502448719955832564080087700747010831668738332060697749893914483616252730277638015091096767677813133913837126520586842957004168892044673
//		  crt coefficient:  2931067481768796750197829654251952834275144311709208657122584273794219248528207319954346442077549609036355755736257063586611921256982012960072866836025831
		
		String digits = &quot;30820276020100300d06092a864886f70d0101010500048202603082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7&quot;;
		byte[] bytes = ByteUtils.toBytesFromHexString(digits);
		
		PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
		spec.readObject();
	}
}
&lt;/PRE&gt;&lt;br /&gt;
실행결과&lt;br /&gt;
&lt;PRE&gt;SEQUENCE Length=630
INTEGER 0
SEQUENCE Length=13
OBJECT_IDENTIFIER 1.2.840.113549.1.1.1
OCTET_STRING 3082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7
&lt;/PRE&gt;&lt;br /&gt;
&lt;br /&gt;단지 흐름만 느끼기 위해서 꼭 필요한 부분만 구현하였다. 실행해보면, 버젼이 0이고, OID가 &quot;1.2.840.113549.1.1.1&quot;이고, 개인키가 &quot;3082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7&quot;라는 것을 알 수 있다.&lt;br /&gt;
&amp;nbsp;&lt;A href=&quot;http://www.oid-info.com/&quot;&gt;http://www.oid-info.com/&lt;/A&gt;를 통해 해당 OID를 조회해보자.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile6.uf.tistory.com/image/183514174B39C50569A12E&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;001.png&quot; height=&quot;455&quot; width=&quot;641&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;너무 당연한 결과이지만 RSA (PKCS #1 v1.5) key transport algorithm라는 것을 친절히 알려준다.&lt;br /&gt;
&amp;nbsp;그럼 PKCS #1을 연구해보자. RFC2313(&lt;A href=&quot;http://www.ietf.org/rfc/rfc2313.txt&quot;&gt;http://www.ietf.org/rfc/rfc2313.txt&lt;/A&gt;)을 보면 된다. 현재 우리가 필요한 부분은 개인키 부분이니, 6페이지로 넘어가자. RSAPrivateKey를 정의한곳이 보인다. INTEGER로 도배가 되어있다. 귀찮은 관계로 조금전 만들 소스를 재활용해서 돌려보자.&lt;br /&gt;
&lt;PRE class=brush:java&gt;		String keyDigits = &quot;3082025c020100028181008be457e074b6b858eab9c2ac7be531eb30b8b61c936ad65943a4d01e777c1459f1184861e633878be716fb31cc8b28ff7c6cdf174eb8b60ff82add86c172aafec5b9b41f1f1ecd6f0a77f07a83e7075458995ba8460a5029320e2affb075df035f6aa399b73520c4b2443d5cbf123a3a1d97ffe44781baadd4d03acfbbe1639102030100010281810087e3c271692eed98823afc9e6ca3d17ff38e1a695bd25671d3c1cfe128944178b538af675a250830a0c4b43245cd907fcdb03c6df9ac783ebf0574b7a846e94ea8f40eaf4b2d590fb288058e386e04eb98707e13a1949b3a55aacd983c7a0714f67407997dc43770da7cf22ee1cdc74a48dcfe66087116370ac7505d0768e801024100e5471b19ae5d167ef5e1d6acef66dd84f4fc64609f4204ef2c35a645eeabaca54c9f56a8e84c268807a55f25a76fcec45f98a2f67528619fb399894d359775d10241009c3242680aafe43a9459a7388fa66a7b2fde15725bc0d1b37a07e43ffc5058d4a53e5d3039c7969c4cc1f672a7aa1a9de1ad44b57f3180b85c5d5747abafc1c102407dcfa8e54cb2b3f773013c05a550b2d9947d32af7a7485b4a073c80bb3cdec6cc040e712c47594e72c1ae8bd06c5e996044703956df07cb15fa22e9f797ae521024045d88bad6ea9fccadd2fc2011eeb71ce28378d2b982fff15dcc9ce9d763c8f9c77500de7d4ce9560cb4a28e458694e81af3b05f08b321db7534642134088d581024037f6c268f9747a8c7b409db9f5e8988b8be091fd264a0164871118031e5cf579d38c701930fc9e5958af188274143126347277b815d7d91ea4fce1c9c4b091e7&quot;;
		byte[] keyBytes = ByteUtils.toBytesFromHexString(keyDigits);
		
		PKCS8EncodedKeySpec x = new PKCS8EncodedKeySpec(keyBytes);
		x.readObject();
&lt;/PRE&gt;&lt;br /&gt;
실행결과&lt;br /&gt;
&lt;PRE&gt;SEQUENCE Length=604
INTEGER 0
INTEGER 98235479183090963770432427642200442983675739444442006745888910614495825811982664163947878578914073870500014846784140598420160562292254019341975013655587919214510314839243283904038428619767073656329177318864029779895278607160852761668068560384471619957237410923582565792151121560119515816871893117811308979089
INTEGER 65537
INTEGER 95424982464164318408735053611818737525775743847171323579913328769092776032507444130876449121730133676301508234676167032006717758161793725366568706522148356314255952502618174670664289187298920132480956331892827405186415397044362320128949328957015105859759408000615566939338475899541162627898412351669762844673
INTEGER 12008250515849944108488102843499187655464462509731422296877150117470960033720378393817005998217639840722804588451011564705219732141220363017738196616705489
INTEGER 8180665372814122660173069738611390116430652686953417350545079644723331346304424811054335466600885913977520264222372188538563562437033369510447765531902401
INTEGER 6589265682759291545683341539251381455754962857240359013081100333010218116982044460357464786424504691274753171641596012785588476849147301445655141778384161
INTEGER 3658125630036325719502448719955832564080087700747010831668738332060697749893914483616252730277638015091096767677813133913837126520586842957004168892044673
INTEGER 2931067481768796750197829654251952834275144311709208657122584273794219248528207319954346442077549609036355755736257063586611921256982012960072866836025831

&lt;/PRE&gt;&lt;br /&gt;
오예~ 값들을 비교해보면 처음 만든 값과 일치하는것을 알 수 있을것이다.~~~ 삽질하느로 수고하셨다. 편히 쉬시길...&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
&amp;nbsp;&lt;/P&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=5265439&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>낙서</category>
			<category>PKCS</category>
			<category>PKCS#8</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/133</guid>
			<comments>http://blog.kangwoo.kr/133#entry133comment</comments>
			<pubDate>Tue, 29 Dec 2009 18:00:06 +0900</pubDate>
		</item>
		<item>
			<title>허무한 11월이 가고</title>
			<link>http://blog.kangwoo.kr/131</link>
			<description>&amp;nbsp;11월은 한것도 없이 시간만 흘러갔다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;공개SW 공모전은 어찌어찌 땜빵하여, 은상을 받았고... (상금도 세금을&amp;nbsp;받아가다니.. --;)&lt;br /&gt;
&amp;nbsp;오픈일에 맞추기 위해, 어플을 3일만에 만들어내는 자기희생을 발휘하기도 했지만, 남는건 배신(?)과 건강 악화 --;&lt;br /&gt;
&amp;nbsp;거기다가 다른 사람 업무를 100% 넘겨 받아서, 어플을 또 하나 개발, 즉 2인분을 하고 있다. 정당한 보상도 없이!!!&lt;br /&gt;
&amp;nbsp;역시, 논리적인 생각보다는 감~~을 따르는게 맞는데, 괜한 욕심을 부렸나 보다.&lt;br /&gt;
&amp;nbsp;자기가 맡은 일만 잘해도, 프로젝트는 잘 돌아갈터인데, 여긴 뭐... 여기저기 빵꾸~~~니. 좌절만...&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;남들이 놀때 같이 놀고, 남들이 일할때 같이 일해야하는데, 남들이 놀때 열심히 일하고, 남들이 열심히 일할때 놀고 있으니....&lt;br /&gt;
&amp;nbsp;갈굼만 당한다.. --; 왜.. 꼭 미리 준비들 안하고, 오픈일이 다가오면 밤샘작업을 하는것인지..... 미리 준비한 내게는 너무나 슬픈 현실이다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;이런 우울한 일들을 날려버리기 위해, 요즘 맛있는 차를 찾아 헤매이고 있는데, 이것도 쉽지만은 않다.&lt;br /&gt;
&amp;nbsp;가장 좋아하는 차는 녹차이지만, 제 맛 나는 녹차를 찾기가 너무 어렵다... 물론 우려내는 방법을 제대로 하지 않아서이기도 하지만...&amp;nbsp;차가&amp;nbsp; 좀... ㅎㅎㅎ&lt;br /&gt;
&amp;nbsp;그래서 대체제로 이슬차를 구매해보았지만, 맛이... 흠흠... 맛있는 이슬차도 많은데, 내가 산건 왜 이모양인지...&lt;br /&gt;
&amp;nbsp;차 속에서 방황하다, 홍차를 구입... 성공이다~~. 원래 홍차는 별로 좋아하지 않지만, 이건 맛이 괜찮은 같아서. 매일 복용중에 있다. 제목은 트와이닝의 브렉페스트~~ 우울한(?) 맛이 너무 맘에 든다...&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;이 우울함으로 가득한 11월에 한 가지 기쁜소식이 생겼다. 그렇게도 기다리는 아이폰 발매~~~&lt;br /&gt;
&amp;nbsp;한시라도 빨리 받고 싶은 마음에, 오늘 잠실실내체육관에 가시 직접 수령을 했는데..... 3시간 동안 추위에 벌벌떨면서 기다렸다... 행사 진행을 이따구로 하는 &#039;크트&#039;가 맘에 안들지만... 아이폰은 역시 예술이다... 아무리봐도 참 잘 만들었다.... 애플의 폐쇄정책은 별로 좋아하지는 않지만, 이런 명품을 만들어내는것을 보면... 정말 멋지다고 밖에 말할 수 없다. 우리나라도 빨리 정신을 차려서 제대로 된 물건 한번 말들었으면 좋겠는데, 매일 삽질이나 하고 있으니....&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;</description>
			<category>넋두리</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/131</guid>
			<comments>http://blog.kangwoo.kr/131#entry131comment</comments>
			<pubDate>Sat, 28 Nov 2009 21:24:24 +0900</pubDate>
		</item>
		<item>
			<title>즐거운 프로젝트</title>
			<link>http://blog.kangwoo.kr/128</link>
			<description>...가, 되고 싶었지만.... 역시 암울한 프로젝트가 되어가고 있다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;일정 관리도 안되고, 갑~의 횡포에 을~은 깨갱~~(본인은 정이다 --;), 한달도 안남았는데, 아직 디자인도 안나오고... 거기다 기획까지 조금 거시기~하고. 후후후... 막판에 고생을 할 생각을 하니 한숨만 나온다. &lt;br /&gt;
&lt;br /&gt;&amp;nbsp;CDC.. 아니 CLDC인가... 암튼 자바 1.3버젼 수준에서 개발을 하려니 많이 괴롭다. 그동안 너무 1.5에 익숙해져 있었던탓인지, 많은 것들을 새롭게 개발(?)해야하는것이다. 가장 큰 문제였던게, URLConnection의 timeout 지정문제였다. 여기서는 전혀 신경을 안쓰고 있기에, 그냥 모른척하고 지나가면 되는것이나... 본인의 그릇된 욕심으로 timeout을 지정하고 싶었다. 구글한테 물어봤더니, 여러가지 방법이 나왔으나, STB에서 정상적으로 작동할지 알 수가 없어서, 그냥 Socket을 사용해 직접 만들었다. Socket을 이용해서 GET 방식으로 호출하고, 응답 결과를 받아오는것이다. 헤더(header)를 정확히 분석하지 않지만, 뭐 작동은 하는거 같으니 그냥 사용해볼까 생각중이다.&lt;br /&gt;
&amp;nbsp;거짓말이다. 반만 정상 작동한다. setSoTimeout은 연결되었을때 읽어들이는 패킷이 없을 경우 타임아웃을 설정하는것이다. 연결할때 타임아웃도 체크하려면...... 어떻하면 좋을까? --; 쓰레드 형님을 불러야하나.. ㅠㅠ&lt;br /&gt;
&lt;PRE class=brush:java&gt;		Socket socket = new Socket(host, port);
		if (timeout &amp;gt; 0) {
			socket.setSoTimeout(timeout);	
		}
		
		StringBuffer header = new StringBuffer();
		header.append(&quot;GET &quot;).append(path).append(&quot; HTTP/1.1&quot;).append(CRLF);
		header.append(&quot;Host: &quot;).append(host).append(CRLF);
		header.append(&quot;Connection: close&quot;).append(CRLF);
		header.append(&quot;User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)&quot;).append(CRLF);
		header.append(&quot;Accept-Encoding: gzip, deflate&quot;).append(CRLF);
		header.append(&quot;Cache-Control: no&quot;).append(CRLF);
		header.append(&quot;Accept-Language: ko&quot;).append(CRLF);
		header.append(CRLF);
		header.append(CRLF);
		
		BufferedReader reader = null;
		PrintWriter writer = null;
		try {
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
			
			// 요청 보내기
			if (Logger.isDebugEnable()) {
				Logger.debug(this, &quot;***********************************************&quot;);
				Logger.debug(this, &quot;&amp;gt; Request Sending&quot;);
				Logger.debug(this, &quot;***********************************************&quot;);
				Logger.debug(this, header.toString());
			}
			
			writer.print(header.toString());
			writer.flush();
			
			if (Logger.isDebugEnable()) {
				Logger.debug(this, &quot;***********************************************&quot;);
				Logger.debug(this, &quot;&amp;gt; Request Sended&quot;);
				Logger.debug(this, &quot;&amp;gt; Waiting Response...&quot;);
				Logger.debug(this, &quot;***********************************************&quot;);
			}
			
			// 원칙적으로는 헤더를 분석한후 charset을 읽어와야하지만 귀찮아서 그냥 둔다.
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), charset));
			
			
			StringBuffer contentSB = new StringBuffer();
			boolean isContent = false;
			String line = null;
			for (int i = 0; (line = reader.readLine()) != null; i++) {
				if (isContent) {
					contentSB.append(line);
				} else {
					if (line.startsWith(&quot;HTTP/1.1&quot;)) {
						String[] array = StringUtils.toArray(line, &quot; &quot;);
						statusCode = Integer.parseInt(array[1]);
					}
				}
				if (isContent == false &amp;amp;&amp;amp; &quot;&quot;.equals(line)) {
					isContent = true;
				}
			}
			
			content = contentSB.toString();
		} finally {
			if (reader != null) try { reader.close(); } catch (IOException ie) {}
			if (writer != null) try { writer.close(); } catch (Exception ie) {}
			if (socket != null) try { socket.close(); } catch (IOException ie) { }
		}
&lt;/PRE&gt;&lt;br /&gt;
&lt;br /&gt;좌절(?)을 딛고, 쓰레드로 구현해본 타임아웃 소켓. 정상 작동 여부는 미지수이다.. 뭔가 엉성하긴 하다. 매번 쓰레드가 생성된다는것. 잘못하면 삑사리가 날 수도 있을거 같다... 요즘 세상에는 뭐 쓸일이 없으니...&lt;br /&gt;
&lt;PRE class=brush:java&gt;import java.io.IOException;
import java.net.Socket;

public class SocketHelper implements Runnable {
	
	private String host;
	private int port;
	
	private Socket socket;
	private boolean hasTimeout;
	
	public SocketHelper(String host, int port) {
		this.host = host;
		this.port = port;
	}

	
	public static Socket createSocket(String host, int port, long connectionTimeout) throws IOException {
		SocketHelper sf = new SocketHelper(host, port);
		Thread thread = new Thread(sf);
		thread.start();
		try {
			thread.join(connectionTimeout);
		} catch (InterruptedException ie) {
			thread.interrupt();
		}
		if (sf.socket == null) {
			sf.hasTimeout = true;
			throw new IOException(&quot;Socket Connection timeout: &quot; + host + &quot;:&quot; + port);
		}
		return sf.socket;
	}

	public void run() {
		hasTimeout = false;
		try {
			socket = new Socket(host, port);
		} catch (IOException ie) {
		}
		if (hasTimeout) {
			if (socket != null) {
				try { socket.close(); } catch(IOException ie) {}
			}
			socket = null;
		}
	}
}

&lt;/PRE&gt;&lt;br /&gt;
&lt;br /&gt;아래는 URLEncoder와 URLDecoder다, charset을 넣는 메소드가 없어서, 구현하려다 귀찮아서 어딘가에서 가져온것인데, 출처는 모르겠다.&lt;br /&gt;
&lt;PRE class=brush:java&gt;import java.io.UnsupportedEncodingException;

public class URLEncoder {
	
	private static final String hex = &quot;0123456789ABCDEF&quot;;
	
	private URLEncoder() {
	}

	/**
	 * This method translates the passed in string into x-www-form-urlencoded
	 * format using the default encoding. The standard encoding is &quot;UTF-8&quot;, and
	 * the two-argument form of this method should be used instead.
	 * 
	 * @param s
	 *            The String to convert
	 * 
	 * @return The converted String
	 * 
	 * @deprecated
	 */
	public static String encode(String s) {
		try {
			// We default to 8859_1 for compatibility with the same
			// default elsewhere in the library.
			return encode(s, System.getProperty(&quot;file.encoding&quot;, &quot;8859_1&quot;));
		} catch (UnsupportedEncodingException uee) {
			// Should never happen since default should always be supported
			return s;
		}
	}

	/**
	 * This method translates the passed in string into x-www-form-urlencoded
	 * format using the character encoding to hex-encode the unsafe characters.
	 * 
	 * @param s
	 *            The String to convert
	 * @param encoding
	 *            The encoding to use for unsafe characters
	 * 
	 * @return The converted String
	 * 
	 * @exception UnsupportedEncodingException
	 *                If the named encoding is not supported
	 * 
	 * @since 1.4
	 */
	public static String encode(String s, String encoding)
			throws UnsupportedEncodingException {
		if (s == null) {
			return null;
		}
		int length = s.length();
		int start = 0;
		int i = 0;

		StringBuffer result = new StringBuffer(length);
		while (true) {
			while (i &amp;lt; length &amp;amp;&amp;amp; isSafe(s.charAt(i))) {
				i++;
			}

			// Safe character can just be added
			result.append(s.substring(start, i));

			// Are we done?
			if (i &amp;gt;= length) {
				return result.toString();
			} else if (s.charAt(i) == &#039; &#039;) {
				result.append(&#039;+&#039;); // Replace space char with plus symbol.
				i++;
			} else {
				// Get all unsafe characters
				start = i;
				char c;
				while (i &amp;lt; length &amp;amp;&amp;amp; (c = s.charAt(i)) != &#039; &#039; &amp;amp;&amp;amp; !isSafe(c)) {
					i++;
				}

				// Convert them to %XY encoded strings
				String unsafe = s.substring(start, i);
				byte bytes[] = unsafe.getBytes(encoding);
				for (int j = 0; j &amp;lt; bytes.length; j++) {
					result.append(&#039;%&#039;);
					int val = bytes[j];
					result.append(hex.charAt((val &amp;amp; 0xf0) &amp;gt;&amp;gt; 4));
					result.append(hex.charAt(val &amp;amp; 0x0f));
				}
			}
			start = i;
		}
	}

	/**
	 * Private static method that returns true if the given char is either a
	 * uppercase or lowercase letter from &#039;a&#039; till &#039;z&#039;, or a digit froim &#039;0&#039;
	 * till &#039;9&#039;, or one of the characters &#039;-&#039;, &#039;_&#039;, &#039;.&#039; or &#039;*&#039;. Such &#039;safe&#039;
	 * character don&#039;t have to be url encoded.
	 */
	private static boolean isSafe(char c) {
		return ((c &amp;gt;= &#039;a&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;z&#039;) || (c &amp;gt;= &#039;A&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;Z&#039;)
				|| (c &amp;gt;= &#039;0&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;9&#039;) || c == &#039;-&#039; || c == &#039;_&#039; || c == &#039;.&#039; || c == &#039;*&#039;);
	}


}
&lt;/PRE&gt;&lt;br /&gt;
&lt;PRE class=brush:java&gt;import java.io.UnsupportedEncodingException;

public class URLDecoder {

	private URLDecoder() {
	}

	/**
	 * This method translates the passed in string from x-www-form-urlencoded
	 * format using the default encoding &quot;UTF-8&quot; to decode the hex encoded
	 * unsafe characters.
	 * 
	 * @param s
	 *            the String to convert
	 * 
	 * @return the converted String
	 * 
	 * @deprecated
	 */
	public static String decode(String s) {
		try {
			return decode(s, &quot;UTF-8&quot;);
		} catch (UnsupportedEncodingException uee) {
			// Should never happen since UTF-8 encoding should always be
			// supported
			return s;
		}
	}

	/**
	 * This method translates the passed in string from x-www-form-urlencoded
	 * format using the given character encoding to decode the hex encoded
	 * unsafe characters.
	 * 
	 * This implementation will decode the string even if it contains unsafe
	 * characters (characters that should have been encoded) or if the two
	 * characters following a % do not represent a hex encoded byte. In those
	 * cases the unsafe character or the % character will be added verbatim to
	 * the decoded result.
	 * 
	 * @param s
	 *            the String to convert
	 * @param encoding
	 *            the character encoding to use the decode the hex encoded
	 *            unsafe characters
	 * 
	 * @return the converted String
	 * 
	 * @exception UnsupportedEncodingException
	 *                If the named encoding is not supported
	 * 
	 * @since 1.4
	 */
	public static String decode(String s, String encoding)
			throws UnsupportedEncodingException {
		// First convert all &#039;+&#039; characters to spaces.
		String str = s.replace(&#039;+&#039;, &#039; &#039;);

		// Then go through the whole string looking for byte encoded characters
		int i;
		int start = 0;
		byte[] bytes = null;
		int length = str.length();
		StringBuffer result = new StringBuffer(length);
		while ((i = str.indexOf(&#039;%&#039;, start)) &amp;gt;= 0) {
			// Add all non-encoded characters to the result buffer
			result.append(str.substring(start, i));
			start = i;

			// Get all consecutive encoded bytes
			while ((i + 2 &amp;lt; length) &amp;amp;&amp;amp; (str.charAt(i) == &#039;%&#039;)) {
				i += 3;
			}
			
			// Decode all these bytes
			if ((bytes == null) || (bytes.length &amp;lt; ((i - start) / 3))) {
				bytes = new byte[((i - start) / 3)];
			}

			int index = 0;
			try {
				while (start &amp;lt; i) {
					String sub = str.substring(start + 1, start + 3);
					bytes[index] = (byte) Integer.parseInt(sub, 16);
					index++;
					start += 3;
				}
			} catch (NumberFormatException nfe) {
				// One of the hex encoded strings was bad
			}

			// Add the bytes as characters according to the given encoding
			result.append(new String(bytes, 0, index, encoding));

			// Make sure we skip to just after a % sign
			// There might not have been enough encoded characters after the %
			// or the hex chars were not actually hex chars
			// (NumberFormatException)
			if (start &amp;lt; length &amp;amp;&amp;amp; s.charAt(start) == &#039;%&#039;) {
				result.append(&#039;%&#039;);
				start++;
			}
		}

		// Add any characters left
		if (start &amp;lt; str.length()) {
			result.append(str.substring(start));
		}
			

		return result.toString();
	}

}
&lt;/PRE&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;</description>
			<category>넋두리</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/128</guid>
			<comments>http://blog.kangwoo.kr/128#entry128comment</comments>
			<pubDate>Tue, 06 Oct 2009 15:50:24 +0900</pubDate>
		</item>
		<item>
			<title>IPTV 관련 소스</title>
			<link>http://blog.kangwoo.kr/127</link>
			<description>&amp;nbsp;ACAP 개발 방식을 기존처럼 한 클래스에 몰빵하는 방식(?)으로 하기로 결정하였다. 구조만 잘 잡혀도, 구조적 프로그래밍을 하는데 별 반감은 없으나... 좀.. 거시기 한것은 어쩔수가 없다. (고생할 생각하니 눈물이 앞을 가리는 구나 ㅠㅠ)&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;여기 첨부하는 소스는 개인적으로 만든 것으로서, IPTV 개발을 좀 더 쉽게 하기 위해 만든, 만들다가만 IPTV 프레임워크라 보면 된다. 이걸로 하자고 밀고 나가고 싶었으나, 요즘 만사가 귀찮아서 그냥 묻어가기로 했다. 아직 테스트 코드가 많고, 많은 부분이 미완성이지만, 차후 또 삽집을 안하기 위해서 여기 흔적을 남겨준다. 저작권(?)상 이미지랑, 해당 업체 관련 코드는 모두 삭제하여으므로, 정상작동을 안한다. 단지 참고용으로만 보면 될것이다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;http://kangwoo.tistory.com/attachment/cfile23.uf@1820B20E4AB314DD81B98F.zip&quot;&gt;&lt;img src=&quot;http://cfs.tistory.com/blog/image/extension/zip.gif&quot; alt=&quot;&quot; style=&quot;vertical-align: middle;&quot; /&gt; iptv-k-src.zip&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;HaviBackgroundController는 잘 작동하는것 같고, VideoController는 STB에서 테스트를 안해봐서 정상 작동 유무를 보장못한다. 그리고, VideoController 부분은 차후 쓰레드로 분리해서 처리해야할거 같다.&lt;br /&gt;
&amp;nbsp;HComponent, HContainer에 보면 자체 더블 버퍼링을 지원하는지 여부를 판단할 수 있는 isDoubleBuffered()를 메소드를 지원한다.&lt;br /&gt;
&amp;nbsp;자체적으로 더블 버퍼링을 할려면, 아래처러 하면 될것이다. 메모리를 좀 더 사용하는게 단점이기는 하지만, 깜빡임을 제거하는데는 이게 최고이다. --;&lt;br /&gt;
&lt;PRE class=brush:java&gt;	Image buffer = null;
	Graphics bufferGraphics = null;
	
	
	public void paint(Graphics g) {
		// Double Buffering
		if (buffer == null) {
			Dimension size = getSize();
			buffer = createImage(size.width, size.height);
			bufferGraphics = buffer.getGraphics();
		}
		// 이미지에  그린다.
		super.paint(bufferGraphics);
		g.drawImage(buffer, 0, 0, this);
	}
&lt;/PRE&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;XleTView에서는 구현안되었던 HAVi UI 위젯(widget)이 실제 xxxxTV의 STB에서는 대부분(?) 잘 작동하였음을 볼 수 있었다.&lt;br /&gt;
&amp;nbsp;그나저나, HDialog 라는게 어떤 API에는 있고, 어떤데는 없는것을 보면 버젼차이인가...? 팝업을 만드는게 상당히 머리를 아프게 만든다. 로직의 제어권이 팝업으로 넘어가버리는 문제가 발생하니... 그냥둬도 뭐 돌아가는데는 문제가 없지만 말이다.&lt;br /&gt;
&lt;br /&gt;
&lt;DIV&gt;
&lt;HR style=&quot;BORDER-TOP-WIDTH: 1px; DISPLAY: block; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: black; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: black; BORDER-TOP-COLOR: black; HEIGHT: 1px; BORDER-RIGHT-WIDTH: 0px; BORDER-RIGHT-COLOR: black&quot;&gt;
&lt;/DIV&gt;&lt;br /&gt;
&amp;nbsp;IPTV를 사용해본 소감은... 실망이었다. 어플이 처음 뜨는 속도가 느린것은 뭐 이해할 수 있으나, 반응속도가 느리고, 셋탑박스 처음 부팅시간은 왜 이리 느린것인지. 셋탁박스 가격도 만만치 않을터인데, 이렇게 밖에 만들 수 없는것인가? 구닥라리 헥박(개조 X-Box)의 XMBC(미디어 플레이어)가 500% 정도 더 좋아보인다. XBMC에 실시간 방송 기능만 추가된다면, IPTV를 가져다 버릴거 같다.......&amp;nbsp;뭐 본인이 모르는 여러가지 제반사항들이 있기는 하지만, 이런 모양새로는 IPTV는 영원히 &quot;보조재&quot;가 될뿐이지 &quot;대체재&quot;가 될 수는 없을것같다.&lt;br /&gt;
&amp;nbsp;차라리 저전력PC에 리모콘 붙인다음, XBMC 같은 미디어 센터 같은 소프트웨어를 올려서 사용하는게 더 미래가 있어보이기까지 한다. (흠 HTPC가 되어버렸네 --;) 하긴 사용자 친화적인 소프트웨어를 만드는게 어렵운것이지만 말이다. 요즘 시대는 하드웨어 조립은, 쉬운편(?)인것 같다. 그에 반해 대한민국 소프트웨어는 아직... 저질인것이다... &lt;br /&gt;
&amp;nbsp;다행이도 요즘에는 XBMC(&lt;A href=&quot;http://xbmc-korea.com/&quot;&gt;http://xbmc-korea.com/&lt;/A&gt;)가&amp;nbsp;여러 플랫폼에서 작동하고, 박씨(&lt;A href=&quot;http://www.boxee.tv/&quot;&gt;www.boxee.tv&lt;/A&gt;) 같은 것도 있으니, 그냥 HTPC 하나 만들어 쓰는게 더 좋을 수도 있다. 거기에다 IPTV처럼 동영상을 합법적이고, 편리하게&amp;nbsp;볼 수 있는 기능이 제공된다면 금상첨화일것 같다.&lt;br /&gt;
&amp;nbsp;사용자가 원하는것은 그리 거창한게 아닐 수도 있다. 단지, 좀 더 편리하고 인간답게(?) 쓰길 원하는것일지도....&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4221873&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>InteractiveTV</category>
			<category>ACAP</category>
			<category>Dobule Buffering</category>
			<category>IPTV</category>
			<category>xlet</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/127</guid>
			<comments>http://blog.kangwoo.kr/127#entry127comment</comments>
			<pubDate>Fri, 18 Sep 2009 13:29:18 +0900</pubDate>
		</item>
		<item>
			<title>심심하다...</title>
			<link>http://blog.kangwoo.kr/126</link>
			<description>&amp;nbsp;요즘 하는게 없어서 그런지 너무 심심하다. 뭐라도 하면 좋으련만, 가을이 와서 그런지 하늘만 보며 꺼이~꺼이~ 울부짖고 있다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;어제는 &quot;큐브리드 인사이드&quot;에 다녀왔다. &quot;저녁 제공&quot;이라는 문구에 혹해서, 한끼 배고픔을 달래고자 가게 되었다. &quot;파우치 샌드위치&quot;라는 색다른 샌드위치를 먹게 되었는데, 생긴것보다는 먹을만해서 행복했다. 역시 배고픈자에게는 CUBRID 2008 R 2.0(High Availability)에 관한 정보 보다는 먹을께 더 행복감을 더해주었다. 소크라 아저씨가 싫어하시겠지만, 배부른 돼지도 나름데로 행복한것이니까.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;강의 내용은&amp;nbsp;좋았지만, 본인의 삐뚫어진 생각은.... &quot;왜&amp;nbsp;활성화(Active) DB가 죽으면 보조(Standby) DB로 전환하는가?&quot; 였다. 애초에 DB를 안죽게 만들면 되는게 아닌가 하는... 말도 안되는 생각만 하고 있었다. (아.. 왜이리 맘이 삐뚫어 졌을까&amp;nbsp;ㅠㅠ)&lt;br /&gt;
&amp;nbsp;고가용성(HA) 즉, 하나의 노드가 문제가 생겼을 경우, 다른 노드로 대체하여 서비스를 계속 제공하는것을 말하는것인데, 큐브리는는&amp;nbsp;heatbeat(&lt;A href=&quot;http://www.linux-ha.org/&quot;&gt;http://www.linux-ha.org/&lt;/A&gt;)를 이용해서 HA를 구현하였다고 한다. 누가 이름을 지었는지는 몰라도, &quot;heatbeat&quot; 작명센스가 아주 훌륭하신거 같다.&lt;br /&gt;
&amp;nbsp;이 HA 기능을 사용하기 위해서는 당연히, 각 DB간에 데이터 동기화가 되어야한다. 큐브리드는(도?) 트랜잭션 로그를 가지고&amp;nbsp;데이터 동기화 작업을 한다. 동기식/비동기식/반동기식 세가지 모드를 지원한다고 한다. 역시. 동기식은 성능의 적일수밖에 없나보다. 이 동기화 작업에 대한 뭔가 획기적인 방법이 나왔으면 하는 생각이 들긴 했지만,&amp;nbsp;아직은 시간이 주도권을 가지고 있을 수 밖에 없는거 같다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4212745&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>넋두리</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/126</guid>
			<comments>http://blog.kangwoo.kr/126#entry126comment</comments>
			<pubDate>Thu, 17 Sep 2009 13:39:37 +0900</pubDate>
		</item>
		<item>
			<title>[퍼옴] 훌륭한 프로그래머는 가난하다. 그가 가난을 벗어나려면 그 &quot;훌륭함&quot;부터 벗어나야 한다.</title>
			<link>http://blog.kangwoo.kr/124</link>
			<description>&lt;P&gt;&lt;br /&gt;
출처 : &lt;A href=&quot;http://unix.co.kr/bbs/board.php?bo_table=03_9&amp;amp;wr_id=11&quot;&gt;http://unix.co.kr/bbs/board.php?bo_table=03_9&amp;amp;wr_id=11&lt;/A&gt;&lt;br /&gt;
&lt;br /&gt;&quot;열심히&quot;씨와 &quot;훌륭한&quot;씨는 각각 &quot;엄청난소프트웨어회사&quot;와 &quot;허벌난소프트웨어회사&quot;의 두 직원이다. 우연치 않게 두 회사에 정확히 똑같은 내용의 주문이 들어왔다. &quot;열나어려운문제&quot; 해결을 위한 프로그램을 작성해 달라는 것이었다. &lt;/P&gt;
&lt;P&gt;열심히씨는 처음 예상 소요 시간인 3개월 동안 정말 열심히 일했다. 하지만 일을 하면서 예상 외의 장애를 직면했고, 밤샘 작업까지 해가면서 3개월의 마지막 날 매니져에게 이런 말을 할 수 있었다. &quot;정말 열나게 프로그램을 짰슴다. 밤샘도 하고요. 제가 지금까지 작성한 프로그램은 2000줄입니다. 그런데, 새로운 문제가 기술적으로 불가피하게 발생했습니다. 복잡한 버그(프로그램의 오류)도 몇 가지 해결해야 하고요. 한 달 가량이 더 필요합니다.&quot; 그러고 한달 후 열심히씨는 몇 개의 버그와 더불어 나름대로 작동하는 프로그램을 매니져와 고객에게 자랑스럽게 보여줄 수 있었다. 벌겋게 충혈된 눈과 미쳐 깎지 못한 수염, 무지무지 어렵고 복잡해 보이는 2500여 줄의 프로그램과 함께. &quot;예상보다 훨씬 더 복잡한 문제였군요. 정말 수고하셨습니다.&quot;라는 칭찬을 들으면서. &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
훌륭한씨는 매니져가 &quot;의무적으로&quot; 잡아놓은 예상 소요 시간 3개월의 첫 2달 반을 빈둥거리며 지냈다. 매니져는 훌륭한씨가 월말이 되어서 &quot;정말 죄송해요. 아직 한 줄도 못짰어요. 너무 어려워요. 좀 봐주세요.&quot;라고 처량하게 자비를 구할 날을 손꼽아 기다렸다. 웬걸, 마지막 날 훌륭한씨는 예의 &quot;너무도 태연스러운&quot; 모습으로 나타났다. 150여 줄의 프로그램과 함께. 그 프로그램은 멋지게 &quot;열나어려운문제&quot;를 해결했다. 하지만, 매니져가 그 코드를 들여다 보자, 한마디로 &quot;너무도 쉬웠다.&quot; 초등학생도 생각해 낼 정도였다. 매니져와 고객은 이름을 &quot;열나쉬운문제&quot;로 바꾸는 데에 전적으로 동의한다. 훌륭한씨는 &quot;이렇게 간단한 문제를 3개월 씩이나 걸려서 풀었습니까? 왜 이렇게 성실하지 못하죠?&quot;라는 비난을 들어야 했다. &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
둘 중에 누가 승진을 했을까? &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
열심히씨는 승진하고, 급여인상을 받았다. 훌륭한씨는 급여삭감을 직면하고는 퇴사해 버렸다. &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
훌륭한 프로그래머는 가난하다. 훌륭한프로그래머의딜레마인 것이다. &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
--김창준 [이 이야기는 SE계의 잘 알려지지 않은 명작 Wicked Problems, Righteous Solutions 에 나온(원래는 CACM 기사였던) 일화를 직접 각색한 것이다] &lt;/P&gt;
&lt;P&gt;&lt;br /&gt;
위나라의 임금이 편작에게 묻는다. &quot;그대 삼형제 가운데 누가 제일 잘 병을 치료하는가?&quot; 큰 형님의 의술이 가장 훌륭하고 다음은 둘째 형님이며 저의 의술이 가장 비천합니다. 임금이 그 이유를 묻자 편작이 대답한 내용은 이러했다. &#039;큰 형님은 상대방이 아픔을 느끼지 전에 얼굴빛을 보고 그에게 장차 병이 있을 것임을 안다. 그리하여 그가 병이 생기기도 전에 원인을 제거하여 준다. 그러므로 상대는 아파보지도 않은 상태에서 치료를 받게 되고 따라서 그간 자기의 고통을 제거해 주었다는 사실을 알지 못한다. 큰 형이 명의로 소문나지 않은 이유는 여기에 있다. 둘째는 상대방이 병세가 미미한 상태에서 그의 병을 알고 치료를 해준다. 그러므로 이 경우의 환자도 둘째형이 자신의 큰 병을 낫게 해주었다고 생각하지 않는다. 그러나 나는 병이 커지고 환자가 고통속에 신음할 때가 되어서야 비로소 병을 알아 보았다. 환자의 병이 심하므로 그의 맥을 짚어야 했으며 진기한 약을 먹이고 살을 도려내는 수술도 했다. 그런데 사람들은 나의 그러한 행위를 보고서야 비로소 내가 자신의 병을 고쳐주었다고 믿게 되었다. 내가 명의로 소문이 나게 된 이유는 여기에 있다.&#039; &lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;/P&gt;
&lt;DIV&gt;
&lt;HR style=&quot;BORDER-RIGHT: black 0px; BORDER-TOP: black 1px solid; DISPLAY: block; BORDER-LEFT: black 0px; BORDER-BOTTOM: black 3px solid; HEIGHT: 7px&quot;&gt;
&lt;/DIV&gt;&amp;nbsp;흠.흠.. 쓸말은 많지만, 적지 않겠다. 아는 사람만 알겠지.. ^^;&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4197762&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>넋두리</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/124</guid>
			<comments>http://blog.kangwoo.kr/124#entry124comment</comments>
			<pubDate>Tue, 15 Sep 2009 21:05:53 +0900</pubDate>
		</item>
		<item>
			<title>내 컴의 추억</title>
			<link>http://blog.kangwoo.kr/123</link>
			<description>&lt;P&gt;&amp;nbsp;감기라 생각되어지는 증상이 나아질 기미를 보이지않는다. 설마.. 신종XX인가... 갑자기 과거의 일들이 떠오른다. 죽을때가 되어가는것인가...? --;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;본인이 처음 접한 컴퓨터는 불행히도 애플이 아니었다. 그것은 바로 SPC-1000이었다. Z80 계열의 8비트 PC였다. 저장장치로는 테잎(Tape)을 사용하였고, 본체와 키보드가&amp;nbsp;붙어있는 일체형이였다. 처음,&amp;nbsp;아는 형 집에 놓여있는 SPC-1000을 보고 눈을 땔 수가 없었다. 짝사랑하는 여인을 멀리는 바라보는 그 아련한 기분이랄까 --; 그러던중 국민학교에 SPC-1500 기종이 무더기로 들어왔고, 컴퓨터부라는것이 만들어진것이었다. 당연히 본인은 가입하였다. 수십대의 SPC-1500 기종과, 선생님 컴퓨터는 5.25인치 플로피 디스크 드라이버까지 장착되어있었다. 맨날 테잎으로 가지고 놀다가, 플로피 디스켓을 봤을때의 그 경이로움은 가히 놀라웠다랄까. 그렇게 SPC-1500과 함께하는 GW-BASIC과 게임들로 국민학교 생활을 마치고... 중학교로 진학하게 되었다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;중학교는 가난했던지, 컴퓨터부 같은것이 없었다. 그래서 부모님을 졸라 컴퓨터 학원을 다니게 되었다. 두 군데의 학원이 있었는데, 한군데는 애플 기종이었고, 나머지 한군데는 IBM PC 호환기종이었다. 본인은 당연히 가격 싼(?) IBM PC 호환기종이 있는 학원을 가게 되었다. 학원에서 쓰던 기종은 SPC-3000. 16비트 교육용(?) 컴퓨터로서 본체와 키보드(86키)가 분리된 형태였다. IBM PC XT 호환기종으로서 보통 XT라 부르던 기억이 난다.&amp;nbsp; Intel 8088-I(10MHz) 프로세서를 탑재하였고, 메모리는 512KB, 5.25인치 2D 디스켓 드라이버를 장착하였고, 그래픽 카드는 허쿨레스 카드, 모니터는 모노크롬 모니터였다. 지금 생각해보면 그 당시 모니터는 진정한 그린(?) 모니터였다. &lt;br /&gt;
&amp;nbsp;학원에서 주로 했던 일은 게임이었다. --; 포트란, 코볼과 전자계산학개론등을 배웠긴 하지만 전혀 기억에 남지 않는다. 이름은 기억나지 않지만, 킹콩들이 빌딩들을 부수는 게임, 덱스터라는 2장짜리 게임(2번째장이 없어서 더이상 진행해보지 못했던 아픈 기억이 ㅠㅠ), 일반적인 복사방법으로 복사되지 않았던 람보라는 게임(COPY II PC 라는 프로그램을 써서 복사해야만 했다.)등 많은 게임이 있었다. 나중에서 카피보드(Deluxe option board, Transcopy)같은 하드웨어를 장치해야만 복사되는 게임도 나왔다.&amp;nbsp;그러고보면, 복사 vs 복사방지의 대결은 참 오래된것 갚다.&amp;nbsp;&lt;br /&gt;
&amp;nbsp;그리고 게임 세이브 파일을 조작하는것도 상당히 재미있었던것 같다. PC-Tools로 세이브 파일의 헥사코드를 편집하여 모든 능력치를 최대로 해서 게임을 하고 하였다. 그 당시 Big-Endian/Little-Endian이라는 개념을 모르는 상태였지만, 수많은 시행착오를 거쳐서, 바이트의 큰 값이 뒤쪽에 저장된다는(Little-Endian) 것을 알아냈다는 사실이 놀라울 따름이었다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;이 시절 본인 최초의 컴퓨터를 얻게되었으니. 그 이름하여 SPC-3100s. 메모리가 640KB에다가 5.25인치 2D 드라이버가 2개 달려고, 그래픽 카드가 무려 CGA를 지원. 거기다가 한글 도깨비 카드까지 장착되어있었다. 그 당시 DOS에서 한글을 사용하려면 한글카드가 필수였다. K-DOS라는 한글 도스가 나왔긴 했지만, 빛을 보지 못하고 역사의 뒤안길로 사라져버렸다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile29.uf.tistory.com/image/2054951A4AA9F6B421DB69&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;247666_6.jpg&quot; height=&quot;426&quot; width=&quot;638&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;한글 얘기가 나왔으니 하는 얘기인데, 그 당시는 조합형 한글을 많이 사용한거 같다. 어찌된 노릇인지 한글 코드의 표준안이 2개가 되어버렸다. 조합형 한글과 완성형 한글. 당연히 한글 구성 원리에 입각하면 조합형 한글을 밀고 나갔어야했는데, 기술적인 문제였는지, 정치적인 문제였는지 몰라도, 엉터리 완성형 한글이 승리하여... 지금까지 유지되어오고 있으니 참 슬픈 노릇이다. 그 당시 한글 코드하면 나오는 얘기가 &quot;똠방각하&quot; 표현문제였다. 완성형 한글은 &quot;똠방각하&quot; 출력이 불가능하였다. 그래서 추후 확장완성형이라는 이상한 괴물이 나오면서 출력이 가능해지게 되었지만. 확장완성형은 코드도 아니여~~~(흔히 보이는 euc-kr이 완성형, MS949가 확장완성형이로고 보면 된다)&lt;br /&gt;
&amp;nbsp;이 당시 컴의 사운드는 사운드가 아니었다. 비프음~ 삑~삑~삑~ 소리만 내었다. 그 저질 소리에도 불구하고, 외장 스피커를 통해 소리를 들어보기 위해서 SPC-3100s의 배를 갈랐다. 내장 스피커 선을 분리하여 외장 스피커 선으로 연결하였다... 퍽~ 불행히 쇼트가 난것인지.. SPC-3100s은 침묵의 컴퓨터가 되어버렸다... ㅠㅠ 이럴수가.. 갖은 노력을 해보았으나 복구 불능이었다. 이대로 영원히 침묵속에서 살아야만 하는가...? &lt;br /&gt;
&amp;nbsp;좌절속에서 생활을 하는 도중 컴퓨터 잡지에서 애드립(AdLiB) 카드라는 것을 보았다. FM 11중 화음의 그 화려한 소리. 결국. 인고의 노력끝에 구입하고 말았다. 처음 장착하고 가동 시키는 순간..... 헉 아무런 소리가 안나는것이었다. 원래 비프음은 내장 스피커로만 나는것이었고, 애드립 카드를 쓸려면 애드립 카드를 지원해주는 프로그램을 써야하는것이었다. --; 뭐 어쨋거나 애드립카드의 생활은 그렇게 시작되었다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile25.uf.tistory.com/image/173C041B4AA9F713497E14&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;adlib.jpg&quot; height=&quot;506&quot; width=&quot;640&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;애드립 카드하면 생각나는 게임이 있을것이다. 바로 &quot;젤리아드&quot;. YS3처럼 액션형 RPG인데, 상당히 재미있는 게임이었다. 거기다 애드립 카드의 소유자만 느낄 수 있는 그 웅장한 사운드는~~ 끝내준다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile30.uf.tistory.com/image/1364460B4AA9AC9040ED74&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;b0017263_23561282.jpg&quot; height=&quot;275&quot; width=&quot;450&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile23.uf.tistory.com/image/1464460B4AA9AC903FCEA1&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;b0016480_148199.gif&quot; height=&quot;275&quot; width=&quot;420&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;Xenon 2라는 슈팅 게임도 재미있게 했다. 이 게임도 애드립 카드를 지원해줬기에 보다 실감나는(?) 게임을 할 수 있었다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile9.uf.tistory.com/image/2064AD0C4AA9AD123522CA&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;c0050643_0201382.jpg&quot; height=&quot;265&quot; width=&quot;442&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile23.uf.tistory.com/image/1164AD0C4AA9AD1236C8CA&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;c0050643_02010157.jpg&quot; height=&quot;265&quot; width=&quot;442&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;이 게임들 뿐만 아니라, 모니터를 뒤집어 놓고 하는(?) 페르시아의 왕자도 참 재미있었던거 같다.&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;중학교시절 &quot;허풍&quot;이라는 친구가 있었다. 이 놈은 이상한 기종의 PC를 가지고 있었는데 바로 MSX 였다. 그것도 MSX X-II / CPC-400s. 초 특급 슈퍼 울트라 하이엔드급 PC였다. 16비트가 난무하던 시절에 8비트의 길을 홀로 외로이 걸어간 멋쟁이인 것이다. 8비트 인것을 빼고는 사실 타의 추종을 불허했다. 흑백 모니터가 난무하던 시절에, 전용 RGB 모니터를 사용하였고, 3.5인치 디스크 드라이버 사용. 비디오 입력단자에다. 기본 사운드도 빵빵한.. 최상의 게임용(?) 컴이였다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile24.uf.tistory.com/image/1616971E4AA9FB689F9B4E&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;x-II.jpg&quot; height=&quot;497&quot; width=&quot;400&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;아 지금 봐도 구미가 당긴다... 이 MSX 게임은 일본 게임이 많았다. 그 유명한 아돌이 나오는 이스(YS) 시리즈, XAK 시리즈, 영웅전설, 대항해시대, 프린세스 메이커, 그라디우스&amp;nbsp;등등.. 정말 역작이 많았다.&lt;br /&gt;
&amp;nbsp;그 놈은 게임기도 종류별로 다 가지고 있었다. 그당시에 패미컴, 슈퍼 패미컴, 메가 드라이브, PC-엔진등을 모두 가지고 있었으니... 진정한 게임 매니아였다.&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4166451&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>넋두리</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/123</guid>
			<comments>http://blog.kangwoo.kr/123#entry123comment</comments>
			<pubDate>Fri, 11 Sep 2009 18:30:00 +0900</pubDate>
		</item>
		<item>
			<title>HTTrack Website Copier</title>
			<link>http://blog.kangwoo.kr/122</link>
			<description>&amp;nbsp;오프라인 브라우저인데, 한마디로 웹사이트를 통째로 다운로드 받아주는 프로그램이다. 프리 소프트웨어라 마음껏 가져다 쓰면 된다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile26.uf.tistory.com/image/1548511D4AA76E1437897A&quot; alt=&quot;&quot; filemime=&quot;image/jpeg&quot; filename=&quot;screenshot_01.jpg&quot; height=&quot;233&quot; width=&quot;300&quot;/&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;&lt;A href=&quot;http://www.httrack.com/&quot;&gt;http://www.httrack.com/&lt;/A&gt;&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;http://kangwoo.tistory.com/attachment/cfile5.uf@1638A01A4AA76E9D0D8877.exe&quot;&gt;&lt;img src=&quot;http://cfs.tistory.com/blog/image/extension/exe.gif&quot; alt=&quot;&quot; style=&quot;vertical-align: middle;&quot; /&gt; httrack-3.43-7.exe&lt;/a&gt;&lt;/div&gt;&amp;nbsp;가끔 javadoc 무단 취식할때 사용한다.. --;&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4147199&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>낙서</category>
			<category>offline browser</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/122</guid>
			<comments>http://blog.kangwoo.kr/122#entry122comment</comments>
			<pubDate>Wed, 09 Sep 2009 18:00:51 +0900</pubDate>
		</item>
		<item>
			<title>Xlet 좌절 중...</title>
			<link>http://blog.kangwoo.kr/120</link>
			<description>&amp;nbsp;알아보지도 못하는 영어 문서를 뒤적거리면서, 드디어 사람답게(?) 개발할 수 있는 방법을 알아내었다.&lt;br /&gt;
&amp;nbsp;HAVi UI에서 각 컴포넌트 별로 UI를 커스터마이징할 수 있도록 HLook 이라는 인터페이스를 제공한다. 문자열 출력같은 경우에는 HText를 생성해서 사용하는데, setLook(HLook) 메소드를 이용해서 상황에 맞게 마음껏 응용할 수 있다. HText를 상속받아 그리는것이 아닌, HLook을 지정하여 그리는 방식인것이다. 거기다가 컴포넌트끼리 이동을 손쉽게 할 수 있는 HNavigable 인터페이스를 제공해서, 특정키를 누르면 대상 컴포넌트로 이동하는것을 너무나도 쉽게 구현할 수 있다. 아아.. 여기까지는 너무 행복했다.&lt;br /&gt;
&amp;nbsp;이론을 검증해보기 위해서 Xlet을 만들어서 테스트를 해보았는데.... 좌절이다.&lt;br /&gt;
&amp;nbsp;몇몇 컴포넌트는 제대로 작동을 하는데, 어떤것들은.... 배째모드이시다. 수많은 삽질의 결과 그 이유는 에뮬레이터에서 지원을 안한다는것이다. &lt;br /&gt;
&amp;nbsp;&lt;A href=&quot;http://www.xletview.org/status/status-current.html&quot;&gt;http://www.xletview.org/status/status-current.html&lt;/A&gt;&amp;nbsp;에 가보면 XleTView가 구현해놓은게 얼마 되지 않는다. --; 2005년도 부터는 개발을 안하는것 같은데...... 흠흠. 거기다가, 에뮬레이터에서 정상 작동해도, 실제 STB에서 정상 작동하는지 보장을 못한다는것이다. 테스트 환경이... 멍멍이판이라서 너무 슬프다. 에뮬레이터가 아닌 STB에 바로 올려서 테스트 해 볼 수 있는 방법은 없을까...?&lt;br /&gt;
&amp;nbsp;본인 생각으로는 IPTV가 성공할려면, 지금처럼 폐쇄적인 환경에서 어플을 개발하는게 아니라, 아이폰 처럼 앱스토어 같은 것을 만들어서, 수많은 개발자들이 어플을 마구 등록하도록 유도하는게 현명한것일터인데... 하긴 우리나라는 하드웨어 조립은 잘해도, 소프트웨어 수준은... 좀 거시기 하니..... 스스로 무덤을&amp;nbsp;팔 수도 있겠다...&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;그나저나, 그냥 무식한 방법으로 구현해나가는 수밖에 없는것인가... 주어진 시간도 얼마없는데.. ㅠㅠ&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;blogger-news-widget&quot; style=&quot;width: 100%; text-align: center&quot;&gt;
		  				&lt;embed src=&quot;http://api.v.daum.net/static/recombox1.swf?nid=4105635&quot; quality=&quot;high&quot; bgcolor=&quot;#ffffff&quot; width=&quot;400&quot; height=&quot;80&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/embed&gt;&lt;/div&gt;</description>
			<category>InteractiveTV</category>
			<category>xlet</category>
			<author>랑우 剛宇</author>
			<guid>http://blog.kangwoo.kr/120</guid>
			<comments>http://blog.kangwoo.kr/120#entry120comment</comments>
			<pubDate>Fri, 04 Sep 2009 16:46:21 +0900</pubDate>
		</item>
	</channel>
</rss>
