어플리케이션 개발시의 고려점 - xrath.com 에서 번역됨

# 어플리케이션 개발시의 고려점

이 장에서는, 다음의 토픽에 대해 설명합니다.

- 처음에
- JAR 파일로부터의 자원의 취득
- 시큐리티와 코드 서명
- 테스트 증명서에 의한 JAR 파일의 서명
- JNLP 파일의 encode 방식
- HTTPS 증명서의 동적 다운로드

### 처음에

Java Web Start 로 배치 가능한 어플리케이션을 개발하는 방법은, Java(TM) Platform Standard Edition 향해의 스탠드얼론 어플리케이션을 개발하는 방법과 기본적으로는 같습니다. 예를 들어, 어플리케이션의 엔드 포인트는, 일반적으로의 `public static void main(String[] argv)` 입니다.

다만, Web 배치 (어플리케이션을 자동적으로 다운로드해 기동하는 것)를 지원해, 어플리케이션을 안전한 샌드 박스내에서 실행하려면 , 고려해야 할 점이 몇개인가 있습니다. 그것들을 다음에 열거합니다.

- 어플리케이션은 일련의 JAR 파일로서 전달될 필요가 있다
- 파일이나 이미지 등, 어플리케이션의 모든 자원은, JAR 파일내에 포함할 필요가 있다. 또, 그러한 자원을 참조하려면 , Java(TM) Platform Standard Edition 의 `getResource` 메카니즘을 사용할 필요가 있다 (자세한 것은 다음을 참조).
- 안전한 샌드 박스내에서 실행되도록(듯이) 기술된 어플리케이션에는, 다음의 제한이 적용된다
  - 로컬 디스크에 액세스 할 수 없다
  - 모든 JAR 파일을 동일 호스트로부터 다운로드할 필요가 있다
  - 네트워크 접속이 유효하게 되어 있는 호스트는, JAR 파일의 다운로드원만이 아니면 안된다
  - 시큐리티 매니저는 인스톨 할 수 없다
  - 네이티브 라이브러리는 사용할 수 없다
  - 시스템 프로퍼티에의 액세스가 제한된다. 어플리케이션은, JNLP 파일내에 정의된 모든 시스템 프로퍼티에 대한 읽기/기입 액세스권을 가지는 것 외에 애플릿으로부터 액세스 가능한 프로퍼티 세트에 대한 읽기 전용 액세스권을 가진다
- 어플리케이션은 `System.exit` 호출을 사용할 수 있는
- 시스템에 대한 무제한의 액세스권을 필요로 하는 어플리케이션은, 일련의 서명 첨부 JAR 파일로서 전달될 필요가 있다. 각 JAR 파일내의 모든 엔트리에 서명할 필요가 있다

### JAR 파일로부터의 자원의 취득

Java Web Start 에 의해 Web 서버로부터 클라이언트 머신에 전송 되는 것은, JAR 파일 뿐입니다. 또, JAR 파일을 로컬 머신상의 어디에 포함할까는, Java Web Start 가 판단합니다. 따라서, 이미지나 설정 파일이라고 하는 자원에의 디스크 상대 참조를, 어플리케이션내에서 사용할 수 없습니다.

모든 어플리케이션 자원은, JNLP 파일의 `resources` 섹션으로 지정된 JAR 파일로부터 취득하는지, Web 서버에의 HTTP 요구를 통해서 명시적으로 취득할 필요가 있습니다. JAR 파일내에 자원을 포함하는 것을 추천합니다. 그렇다고 하는 것도, 그러한 자원은, Java Web Start 에 의해 로컬 머신상에 캐쉬되기 때문입니다.

다음의 코드예는, JAR 파일로부터 이미지를 꺼내는 방법을 나타낸 것입니다.

`// Get current classloader`
`ClassLoader cl = this. getClass(). getClassLoader();`
`// Create icons`
`Icon saveIcon = new ImageIcon(cl.getResource("images/save.gif"));`
`Icon cutIcon = new ImageIcon(cl.getResource("images/cut.gif"));`
`...`

이 예에서는, 어플리케이션의 JAR 파일의 어느 쪽인가에, 다음의 엔트리가 존재하는 것을 전제로 하고 있습니다.

> `images/save.gif`
> `images/cut.gif`

### 시큐리티와 코드 서명

Java Web Start 는, 시큐리티상의 문제에 다음과 같이 대응하고 있습니다.

- 로컬 파일에 영향을 미칠 가능성이 있는 유해한 코드 (의도적인가 어떤가에 관계없이)로부터, 사용자를 보호한다.
- 네트워크상의 데이터에 대해서 액세스나 파괴를 시도할 가능성이 있는 코드로부터, 기업을 보호한다

Java Web Start 로 기동된 어플리케이션은 디폴트로, 제한된 환경내에서 실행됩니다. 이 때문에, 기억장치나 로컬 네트워크 등, 로컬의 컴퓨팅 자원에의 액세스가 제한됩니다. 이 샌드 박스 환경내에서는, Java Web Start 는, 다운로드된 신뢰할 수 없을 가능성이 있는 어플리케이션에 의해 로컬의 파일이나 네트워크의 시큐리티가 저하하지 않는 것을 보증할 수 있습니다.

Java Web Start 가 지원하는 이제(벌써) 1 개의 시큐리티 기능은, 디지털 코드 서명입니다. 기동 대상의 어플리케이션이 1 개 또는 복수의 서명 첨부 JAR 파일로서 전달되었을 경우, Java Web Start 는, 그러한 JAR 파일의 내용이 서명 후로 변경되어 있지 않은지 어떤지 검증합니다. 디지털 서명의 검증에 실패했을 경우, 그 어플리케이션은 제삼자에 의해 조작된 가능성이 있기 (위해)때문에, Java Web Start 는 어플리케이션의 실행을 중지합니다.

코드 서명의 지원는, 사용자와 어플리케이션 서비스 프로바이더의 쌍방에 있어 중요합니다. 이 서비스를 사용하면, 사용자는, 어플리케이션의 제공원을 신뢰할 수 있을지 어떨지를 검증할 수 있습니다. 코드에 서명하는 것은 어플리케이션 서비스 프로바이더이기 (위해)때문에, 그 어플리케이션에 대해서 Web 상의 제삼자가 위장할 수 없는 것이, 사용자와 프로바이더의 양자에 대해서 보증됩니다. 또, 사용자에 의해 신뢰된 서명 첨부의 어플리케이션은, 로컬 디스크에의 액세스 등, 추가의 시스템 권한을 요구할 수도 있습니다.

Java Web Start 는, 어플리케이션을 기동하기 전에, 서명자의 증명서에 근거해, 어플리케이션의 제공원을 나타내는 다이얼로그를 표시합니다. 이것에 의해, 사용자는, 다운로드된 코드에 추가의 권한을 허가해야할 것인가 제발을, 구체적인 정보에 근거해 결정할 수가 있습니다.

어플리케이션의 모든 JAR 파일이 서명되고 있으면, JNLP 파일내에 다음의 설정을 포함하는 것으로, 어플리케이션은 클라이언트 시스템에의 완전한 액세스를 요구할 수 있게 됩니다.

`<security>`
`<all-permissions/>`
`</security>`

Java Web Start 에 있어서의 코드 서명의 구현은, 코어 Java(TM) Platform Standard Edition 의 시큐리티 API 에 근거하고 있습니다. Java 2 SE JRE 1.4. 2 는, SHA1withDSA, MD5withRSA 의 양아르고리즈에 의한 코드 서명을 지원하고 있습니다.

개발자가 Java Web Start 용의 코드에 서명하는 방법은, Java 애플릿의 경우와 같습니다. 즉, Java(TM) Platform Standard Edition 에 부속되는 표준 툴 `jarsigner` 를 사용합니다. `jarsigner` 툴의 메뉴얼에서는, 코드의 서명 방법과 테스트 증명서의 작성 방법의 구체적인 예를 나타내는 것과 동시에, 서명에 관한 그 외의 문제에 대해 설명하고 있습니다.

또, Java Web Start 에서는, SDK/JRE 1.4. 2 와 함께 사용하는 Netscape `signtool` 의 사용도 지원하고 있습니다. 자세한 것은 Netscape 의 Web 사이트를 참조해 주세요. http://developer.netscape.com/software/signedobj/

### 테스트 증명서에 의한 JAR 파일의 서명

다음에, 테스트 증명서를 사용해 JAR 파일에 서명하는 순서를 나타냅니다.

1. SDK 1.4. 2 의 `keytool` 와 `jarsigner` 에 패스가 다니고 있는 것을 확인합니다. 이러한 툴은, SDK 의 bin 디렉토리에 포함되고 있습니다.

2. 새로운 `keystore` 내에 새로운 키를 작성합니다. 다음과 같이 합니다.

> > `keytool -genkey -keystore myKeystore -alias myself`

> 패스워드, 이름 등 새로운 키에 관한 정보의 입력이 요구됩니다. 이 정보에 근거해, 디스크에 `myKeystore` 파일이 작성됩니다.

3. 계속되어, 자기 서명 테스트 증명서를 작성합니다. 다음과 같이 합니다.

> `keytool -selfcert -alias myself -keystore myKeystore`

> 증명서를 작성하면(자), 패스워드의 입력이 요구됩니다. 증명서의 생성에는 몇분 걸립니다.

4. 모든 것이 정상적인 것을 확인합니다. 키스토어의 내용을 일람표시 하려면 , 다음의 커멘드를 사용합니다.

> `keytool -list -keystore myKeystore`

> 커멘드에 의해, 다음과 같은 일람이 표시됩니다.

> > `Keystore type:jks
> > Keystore provider:SUN
> > Your keystore contains 1 entry:
> > myself, Tue Jan 23 19:29:32 PST 2001, keyEntry,
> > Certificate fingerprint (MD5):
> > C2:E9:BF:F9:D3:DF:4C:8F:3C:5F:22:9E:AF:0B:42:9D`

5. 마지막으로, 테스트 증명서를 사용해 JAR 파일에 서명합니다. 다음과 같이 합니다.

> `jarsigner -keystore myKeystore test.jar myself`

> 이 순서를, 모든 JAR 파일에 대해서 반복합니다.

자기 서명 테스트 증명서는 어디까지나 내부 테스트 전용인 것에 주의해 주세요. 이 증명서는 사용자의 신원을 보증하지 못하고, 신뢰성이 부족하기 때문입니다. 어플리케이션을 실전 환경으로 옮기려면 ,VeriSign 나 Thawte 등의 인증국으로부터 신뢰할 수 있는 증명서를 취득해, 그것을 사용하도록 해 주세요.

### JNLP 파일의 encode 방식

Java Web Start 의 버젼 1.2 이후, Java(TM) Platform Standard Edition 로 지원되고 있는 임의의 문자 인코딩을 사용해, JNLP 파일을 encode 할 수 있게 되었던 (지원되고 있는 인코딩의 일람에 대해서는,Java(TM) Platform Standard Edition 문서를 참조).

JNLP 파일을 encode 하려면 , 그 파일의 XML prolog 로 인코딩을 지정합니다. 예를 들어, 다음의 행은, JNLP 파일을 UTF-16 로 encode 하는 것을 나타내고 있습니다.

>     <? xml version="1.0" encoding="utf-16"? >

XML prolog 그 자체는, UTF-8 로 encode 할 필요가 있습니다.

### HTTPS 증명서의 동적 다운로드

1.4. 2 이후, Java Web Start 에서는, 브라우저와 거의 같은 방법으로 증명서가 동적으로 임포트 됩니다. 이 때문에, 현재, Java Web Start 에서는,`java.protocol.handler.pkgs` 시스템 프로퍼티을 사용해 `SSLSocketFactory` 와 `HostnameVerifier` 의 양디폴트를 초기화하는 https 핸들러가 독자적으로 설정되어 있습니다. 디폴트의 설정에는,`HttpsURLConnection.setDefaultSSLSocketFactory` 와 `HttpsURLConnection.setDefaultHostnameVerifier` 가 사용됩니다.

어플리케이션내에서 이것들 2 개의 메소드가 사용되고 있는 경우, Java Web Start 의 https 핸들러의 초기화 후에 그러한 메소드를 호출하도록 해 주세요. 그렇게 하지 않으면 어플리케이션의 커스텀 핸들러가, Java Web Start 의 디폴트 핸들러로 옮겨놓을 수 있어 버립니다. 독자적으로 커스터마이즈 된 `SSLSocketFactory` 과 `HostnameVerifiter` 가 사용되도록(듯이) 하려면 , 다음의 어느쪽이든을 실행합니다.

1. 독자적인 https 핸들러를 인스톨 하는 것으로, Java Web Start 의 https 핸들러를 완전하게 옮겨놓는다 (자세한 것은,「A New Era for Java Protocol Handlers」를 참조)
2. `HttpsURLConnection.setDefaultSSLSocketFactory` 또는 `HttpsURLConnection.setDefaultHostnameVerifier` 의 호출을, 반드시 최초의 https url 객체가 작성된 후에 실시한다 (그러면, Java Web Start 의 https 핸들러의 초기화 코드가 최초로 실행된다)

다운로드 서브 렛의 작성의 자세한 것은, 다음의 장,「JnlpDownloadServlet 가이드」를 참조해 주세요.