버릴 수 있는 ì¡°êµì´ 있다면 ê·¸ê²ƒì€ ì• ë‹¹ì´ˆ 지니지 ì•Šì•˜ë˜ ì¡°êµì´ë‹¤. ―김소운
 * ì›ë¬¸ë§í¬ :
http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html
http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html
- íìŒ... ì›¹ì— ì˜¬ë¦´ë•Œì—는 ì²˜ìŒ ìƒì„±í•œ ì¸ì¦í‚¤ë¥¼ ì 용한 jarí™”ì¼ë§Œ 있으면 ë˜ëŠ”êµ°ìš”. ê·¼ë° JRE2 를 별ë„로 깔아야하는 ì ì€ ì¢€ 단ì ì´ë„¤ìš”.
1 시작하며 #
ì •ì±…(policy) í™”ì¼ì€ ì´ í™”ì¼ì„ 사용하여 ë™ìž‘í•˜ê³ ìž í•˜ëŠ” ëª¨ë“ ì• í”Œë¦¿ ë˜ëŠ” 어플리케ì´ì…˜ìƒì—ì„œì˜ ì „ìžì„œëª…ì„ ìš”êµ¬í•˜ë„ë¡ ì •ì˜ë 수 있습니다. ì „ìžì„œëª…ì€ ì–´í”Œë¦¿ ë˜ëŠ” 어플리케ì´ì…˜ì´ 믿ì„만한 ì œê³µìžê°€ ì œê³µí•œ 것ì´ê³ ì •ì±… í™”ì¼ì—서 허가한 권한(permission)ì„ ì‚¬ìš©í•˜ì—¬ ì‹¤í–‰í•˜ëŠ”ë° ìžˆì–´ì„œ ì‹ ë¢°í• ìˆ˜ 있는지 여부를 ê²€ì¦í•˜ëŠ” 방법입니다.
만약 ì •ì±… í™”ì¼ì´ ì „ìžì„œëª…ì„ í•„ìš”ë¡œí•˜ë©´, ì• í”Œë¦¿ ë˜ëŠ” 어플리케ì´ì…˜ì€ ì •í™•í•œ ì „ìžì„œëª…ì„ ê°€ì§€ê³ ìžˆì„때ì—ë§Œ ì •ì±…í™”ì¼ì—서 수ë½í•œ ì ‘ê·¼ê¶Œí•œì„ ì–»ì„ ìˆ˜ 있습니다. 만약 ì• í”Œë¦¿ ë˜ëŠ” 어플리케ì´ì…˜ì´ 틀린 ì „ìžì„œëª…ì„ ê°€ì§€ê³ ìžˆê±°ë‚˜ ì „ìžì„œëª…ì„ ê°€ì§€ê³ ìžˆì§€ 않다면 í™”ì¼ì— ì ‘ê·¼í• ìˆ˜ 있는 ê¶Œí•œì„ ì–»ì„ ìˆ˜ 없습니다.
ì´ ì•„í‹°í´ì—서는 ì• í”Œë¦¿ì— ì„œëª…í•˜ê³ , ì „ìžì„œëª…ì„ ê²€ì¦í•œë‹¤ìŒ, ì •ì±…í™”ì¼ì„ 사용하여 ì• í”Œë¦¿ì„ ì‹¤í–‰í•˜ëŠ” 예를 ë”°ë¼ê°€ë³´ë„ë¡ í•˜ê² ìŠµë‹ˆë‹¤.
2 ì„œëª…ëœ ì• í”Œë¦¿ ì˜ˆì œ #
ì •ì±…í™”ì¼ ì ‘ê·¼í—ˆê°€ëŠ” ì „ìžì„œëª…ì„ ìš”êµ¬í•˜ê±°ë‚˜, 요구하지 않ë„ë¡ ì„¤ì •í• ìˆ˜ 있습니다. 만약 ì „ìžì„œëª…ì„ ìš”êµ¬í•˜ëŠ” 경우ë¼ë©´, ì• í”Œë¦¿ì€ ì„œëª…ë˜ê¸° ì´ì „ì— Java ARchive(JAR)í™”ì¼ë¡œ í¬ìž¥ë˜ì–´ìžˆì–´ì•¼í•©ë‹ˆë‹¤. ì´ ì˜ˆì œëŠ” ì• í”Œë¦¿ì— ì„œëª…í•˜ê³ ê¶Œí•œì„ ë¶€ì—¬í•¨ìœ¼ë¡œì„œ, ì• í”Œë¦¿ ë·°ì–´ì—서 ì‹¤í–‰í• ë•Œ ì‚¬ìš©ìž home ë””ë ‰í† ë¦¬ì•ˆì— demo.ini를 ìƒì„±í• 수 있ë„ë¡í•˜ëŠ” 방법으로 ë³´ì—¬ì¤ë‹ˆë‹¤.
ë‹¤ìŒ í™”ì¼ë“¤ì€ ì˜ˆì œì—서 사용하는 í™”ì¼ë“¤ìž…니다. (ë¶€ë¡ì°¸ì¡°) ì´ í™”ì¼ë“¤ì„ ì—¬ëŸ¬ë¶„ì˜ ìž‘ì—… ë””ë ‰í† ë¦¬ì— ìƒì„±í•˜ê±°ë‚˜ 복사해놓으ì‹ì‹œìš”.
ì¼ë°˜ì 으로 ì• í”Œë¦¿ì€ ì¸íЏë¼ë„· 개발ìžì— ì˜í•´ í¬ìž¥ë˜ê³ 서명ëœë‹¤ìŒ ì „ìžì„œëª…ì„ ê²€ì¦í•˜ê³ ì• í”Œë¦¿ì„ ì‹¤í–‰í• ìµœì¢…ì‚¬ìš©ìžì—게 건네집니다. ì´ ì˜ˆì œì—서는 ì¸íЏë¼ë„· 개발ìžëŠ” 1단계ì—서 5단계까지를 ì‹¤í–‰í•˜ê³ , 최종사용ìžëŠ” 6단계ì—서 8단계까지를 실행합니다. 간단하게 설명하기위해서 ëª¨ë“ ê³¼ì •ì€ ê°™ì€ ìž‘ì—…ë””ë ‰í† ë¦¬ì—서 진행하ë„ë¡ í•˜ê² ìŠµë‹ˆë‹¤.
3 ì¸íЏë¼ë„· ê°œë°œìž #
ì¸íЏë¼ë„· 개발ìžëŠ” JAR í™”ì¼ì•ˆì— ì• í”Œë¦¿ì„ í¬ìž¥í•˜ê³ , JARí™”ì¼ì— 서명한다ìŒ, public key ì¸ì¦ì„œë¥¼ 추출합니다.
3.2 JAR í™”ì¼ ë§Œë“¤ê¸° #
ê·¸ëŸ°ë‹¤ìŒ ì»´íŒŒì¼ëœ SignedAppletDemo.class를 JARí™”ì¼ì— 담습니다. jar ëª…ë ¹ì— cvf ì˜µì…˜ì„ ë¶™ì—¬ 실행하면, 새로운 ì•„ì¹´ì´ë¸Œí™”ì¼ì„ ë§Œë“¤ê³ (c), verbose 모드를 사용하며(v), ì•„ì¹´ì´ë¸Œ í™”ì¼ëª…ì„ ì§ì ‘ ì§€ì •í•©ë‹ˆë‹¤(f). ìƒì„±ëœ ì•„ì¹´ì´ë¸Œí™”ì¼ì€ SignedApplet.jarì´ ë©ë‹ˆë‹¤.
jar cvf SignedApplet.jar SignedAppletDemo.class
3.3 키 ìƒì„±í•˜ê¸° #
JAR í™”ì¼ì€ JARí™”ì¼ì„ ìƒì„±í•œ ì‚¬ëžŒì˜ private키를 사용하여 서명ë˜ë©°, ê·¸ ì„œëª…ì€ ì´ì™€ 한ìŒì¸ public키를 사용하여 JARí™”ì¼ì˜ ìˆ˜ë ¹ìžì— ì˜í•´ ê²€ì¦ë©ë‹ˆë‹¤. The certificate is a statement from the owner of the private key that the public key in the pair has a particular value so the person using the public key can be assured the public key is authentic. public키와 private키는 jarsigner를 사용하여 JARí™”ì¼ì— 서명하거나 ì„œëª…ì„ ê²€ì¦í• 때는 ì–¸ì œë‚˜ keystore ë°ì´íƒ€ë² ì´ìŠ¤ì•ˆì— ì¡´ìž¬í•´ì•¼ë§Œí•©ë‹ˆë‹¤.
다ìŒê³¼ ê°™ì´ ê°œë°œìžëŠ” keystore ë°ì´íƒ€ë² ì´ìŠ¤ë¥¼ ìƒì„±í•˜ê³ í‚¤ë“¤ì„ ìƒì„±í•©ë‹ˆë‹¤:
keytool -genkey -alias signFiles -keystore compstore -keypass kpi135 -dname "cn=jones" -storepass ab987cì´ keytool -genkey ëª…ë ¹í˜¸ì¶œì€ alias signFilesì— ì˜í•´ ì‹ë³„ë˜ëŠ” 키 ìŒì„ ìƒì„±í•˜ê²Œ ë©ë‹ˆë‹¤. 나머지 keytool ëª…ë ¹ í˜¸ì¶œì€ ìƒì„±ëœ 키ìŒì¤‘ privateí‚¤ì— ì ‘ê·¼í•˜ê¸°ìœ„í•œ alias와 키 암호(-keypass kpi135)를 사용합니다.
ìƒì„±ëœ 키ìŒì€ í˜„ìž¬ë””ë ‰í† ë¦¬ì•ˆì˜ compstoreë¼ê³ 하는 keystore ë°ì´íƒ€ë² ì´ìФ í™”ì¼ì— ì €ìž¥ë©ë‹ˆë‹¤(-keystore compstore). ê·¸ë¦¬ê³ compstoreì— ì ‘ê·¼í•˜ê¸° 위한 암호를 ì§€ì •í•©ë‹ˆë‹¤(-storepass ab987c).
-dname "cn=jones"ì˜µì…˜ì€ commonName(cn)ê°’ì„ ì‚¬ìš©í•˜ì—¬ X.500 ì‹ë³„명ì¹ì„ ì •ì˜í•©ë‹ˆë‹¤. X.500 ì‹ë³„ëª…ì€ X.509 ì¸ì¦ì„œ 개체를 ì‹ë³„í•˜ëŠ”ë° ì‚¬ìš©í•©ë‹ˆë‹¤. ì´ ì˜ˆì œì—서는 개발ìžì˜ ì„±ì„ ë”°ì„œ Jonesë¼ê³ ì§€ì •í•˜ê³ ìžˆìŠµë‹ˆë‹¤. ì•„ë§ˆë„ ê°ìžì˜ 목ì ì— ë§žì¶°ì„œ ì´ë¶€ë¶„ì€ ì•Œë§žê²Œ ë³€ê²½í• ìˆ˜ 있ì„ê²ë‹ˆë‹¤.
keytoolì— ëŒ€í•œ ëª¨ë“ ì˜µì…˜ê³¼ 매개변수를 ë³´ë ¤ë©´ 다ìŒê³¼ê°™ì´ 실행하면 ë©ë‹ˆë‹¤:
keytool -help
3.4 JAR í™”ì¼ì— 서명하기 #
jarsigner는 JAR í™”ì¼ì— ì„œëª…í•˜ê³ ì„œëª…ì„ ê²€ì¦í•˜ê¸°ìœ„한 ëª…ë ¹í–‰ 툴입니다. 개발ìžëŠ” SignedApplet.jarì˜ ì„œëª…ëœ ë³µì‚¬ë³¸ì„ ë§Œë“¤ê¸°ìœ„í•´ jarsigner를 사용합니다.
jarsigner -keystore compstore -storepass ab987c
-keypass kpi135
-signedjar
SSignedApplet.jar SignedApplet.jar signFiles
-storepass ab987c와 -keystore compstoreì˜µì…˜ì€ JAR í™”ì¼ì— ì €ìž¥ë ì„œëª…ì— ëŒ€í•œ private키가 ì €ìž¥ëœ keystore ë°ì´íƒ€ë² ì´ìŠ¤í™”ì¼ê³¼ 암호를 ì§€ì •í•©ë‹ˆë‹¤. -keypass kpi135ì˜µì…˜ì€ private키 암호ì´ë©°, ê·¸ë‹¤ìŒ ì˜µì…˜ì¸ SSignedApplet.jar는 ìƒì„±ë ì„œëª…ëœ JARí™”ì¼ëª…, ê·¸ë¦¬ê³ signFilesì€ privateí‚¤ì˜ alias를 나타냅니다. jarsigner는 keystore로부터 signFilesí•ëª©ì— í•´ë‹¹í•˜ëŠ” ì¸ì¦ì„œë¥¼ ì¶”ì¶œí•œë‹¤ìŒ ì„œëª…ëœ JARí™”ì¼ì— ìƒì„±ëœ ì „ìžì„œëª…ì„ ì²¨ë¶€í•©ë‹ˆë‹¤.
3.5 public 키 ì¸ì¦ì„œ 추출하기 #
public 키 ì¸ì¦ì„œëŠ” ì• í”Œë¦¿ì„ ì‚¬ìš©í•˜ê²Œë 최종사용ìžì—게 JARí™”ì¼ê³¼ 함께 ì „ì†¡ë©ë‹ˆë‹¤. ì´ ì‚¬ìš©ìžëŠ” JARí™”ì¼ì— 있는 ì „ìžì„œëª…ì— ì¸ì¦í•˜ê¸°ìœ„í•´ ì´ ì¸ì¦ì„œë¥¼ 사용하게 ë©ë‹ˆë‹¤. ì¸ì¦ì„œëŠ” compstore ë°ì´íƒ€ë² ì´ìŠ¤í™”ì¼ì—서 추출하여 ì „ì†¡ë©ë‹ˆë‹¤.
개발ìžëŠ” compstore로부터 CompanyCer.cerë¼ëŠ” ì´ë¦„ì˜ í™”ì¼ë¡œ ì¸ì¦ì„œë¥¼ 복사하기위해 다ìŒê³¼ ê°™ì´ keytoolì„ ì‚¬ìš©í•©ë‹ˆë‹¤:
keytool -export -keystore compstore -storepass ab987c -alias signFiles -file CompanyCer.cer마지막으로 웹페ì´ì§€ìƒì˜ ë°°í¬ ë””ë ‰í† ë¦¬ì— JAR와 ì¸ì¦ì„œ í™”ì¼ì„ 업로드하면 ëª¨ë“ ìž‘ì—…ì´ ë납니다.
4 ìµœì¢…ì‚¬ìš©ìž #
Ray, the end user, downloads the JAR file from the distribution directory, imports the certificate, creates a policy file granting the applet access, and runs the applet.
4.1 ì‹ ë¢°í•˜ëŠ” ì¸ì¦ì„œë¡œì„œ ì¸ì¦ì„œë¥¼ 수ë½í•˜ê¸° #
Ray downloads SSignedApplet.jar and CompanyCer.cer to his home directory. Ray must now create a keystore database (raystore) and import the certificate into it using the alias company. Ray uses keytool in his home directory to do this:
keytool -import -alias company -file
CompanyCer.cer -keystore
raystore -storepass abcdefgh
4.2 ì •ì±… í™”ì¼ ìƒì„±í•˜ê¸° #
The policy file grants the SSignedApplet.jar file signed by the alias company permission to create demo.ini (and no other file) in the user's home directory.
Ray creates the policy file in his home directory using either policytool or an ASCII editor.
keystore "/home/ray/raystore";
// A sample policy file that lets a program
// create demo.ini in user's home directory
// Satya N Dodda
grant SignedBy "company" {
permission java.util.PropertyPermission
"user.home", "read";
permission java.io.FilePermission
"${user.home}/demo.ini", "write";
};
4.3 ì• í”Œë¦¿ ë·°ì–´ì—서 ì• í”Œë¦¿ì„ ì‹¤í–‰í•˜ê¸° #
Applet Viewer connects to the HTML documents and resources specified in the call to appletviewer, and displays the applet in its own window. To run the example, Ray copies the signed JAR file and HTML file to /home/aURL/public_html and invokes Applet viewer from his home directory as follows:
appletviewer -J-Djava.security.policy=Write.jp http://aURL.com/SignedApplet.htmlNote: Type everything on one line and put a space after Write.jp
The -J-Djava.security.policy=Write.jp option tells Applet Viewer to run the applet referenced in the SignedApplet.html file with the Write.jp policy file.
Note: The Policy file can be stored on a server and specified in the appletviewer invocation as a URL.
5 ì •ì±…í™”ì¼ì„ 사용하여 어플리케ì´ì…˜ì„ 실행하기 #
This application invocation restricts MyProgram to a sandbox-like environment the same way applets are restricted, but allows access as specified in the polfile policy file.
java -Djava.security.manager
-Djava.security.policy=polfile MyProgram
6.1 SignedAppletDemo.java #
/*
* File: @(#)SignedAppletDemo.java 1.1
* Comment: Signed Applet Demo
*
* @(#)author: Satya Dodda
* @(#)version: 1.1
* @(#)date: 98/09/11
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.io.*;
import java.awt.Color;
/**
*
* A simple Signed Applet Demo
*
*/
public class SignedAppletDemo extends Applet {
public String test() {
setBackground(Color.white);
String fileName = System.getProperty("user.home") +
System.getProperty("file.separator") +
"demo.ini";
String msg = "This message was written by a signed applet!!!\n";
String s ;
try {
FileWriter fos = new FileWriter(fileName);
fos.write(msg, 0, msg.length());
fos.close();
s = new String("Successfully created file :" + fileName);
} catch (Exception e) {
System.out.println("Exception e = " + e);
e.printStackTrace();
s = new String("Unable to create file : " + fileName);
}
return s;
}
public void paint(Graphics g) {
g.setColor(Color.blue);
g.drawString("Signed Applet Demo", 120, 50);
g.setColor(Color.magenta);
g.drawString(test(), 50, 100);
}
}









