IT_Programming/Java

Java Security Manager & Java policy 파일 생성

JJun ™ 2011. 6. 10. 14:24

------------------------------------------------------------------------------------------------

출처: http://blog.naver.com/clean820818/10037273123

참고: http://www.javastudy.co.kr/docs/jhan/javaadvance/index.html#contents

------------------------------------------------------------------------------------------------

 

 


 

Java Security Manager (Java 보안 관리자)

 

보안 관리자는 보안 정책을 구현한 자바 가상 머신 객체이다.

기본적으로, 자바 2 플랫폼 소프트웨어는 로컬 시스템 자원들을 접근할 수 있는 모든 권한을 허가하지 않는 보안 관리자를 제공한다.

 

프로그램은 로컬 시스템 자원들 즉, 프로그램이 실행된 디렉토리와 그 하위 디렉토리를 읽을 수도 없다.

(A security manager is a JavaTM virtual machine (VM) object that implements a security policy. By default, the Java 2® platform software provides a security manager that disallows all access to local system resources apart from read access to the directory and its subcirectories where the program is invoked.)

 

프로그래머는 기본 보안 관리자를 애플릿이나 애플리케이션에서 자신의 환경에 적절하게 확인과 승인을

구현함으로 확장할 수 있다. 그러나, 구현은 재정의한 모든 checkXXX 메서드에 대하여 적합한 접근 확인 코드를 포함하여야 한다. 만약 이러한 코드를 포함하지 않는다면, 접근 권한을 확인할 수 없고,

따라서 코드는 시스템 보안 정책으로 분기된다.(You can extend the default security manager to implement customized verifications and approvals for applets and applications, but the implementation must include the appropriate access verification code for every checkXXX method you override. If you do not include this code, no access verfication check happens, and your code breaches the system security policy.)

 

이 절에서는 각자에게 맞는 보안 관리자를 어떻게 작성하는지 설명하기 위해서 예제 애플리케이션을

사용한다. 여기에서는 각자에게 맞는 보안 관리자의 예제로서 명시된 파일로부터 읽거나 명시된 파일에

무엇인가를 쓰기 전에 패스워드 확인을 위해서 사용자에게 물어보는 보안 관리자이다.

 

구현은 접근 권한 확인 코드를 포함하고 있어서 사용자가 패스워드 체크를 통해서 파일에 한 번 접근하고

나면, 정책 파일에서는 파일을 읽고 쓸 수 있는 권한을 여전히 필요로 한다.

(This section uses an example application to explain how to write a custom security manager that prompts the end user for password identification before reading from and writing to specific files. The implementation includes access verification code so once the end user makes it through the password check, he or she still needs the file read and write permissions in their policy file.)

 

예제는 FileIO 애플리케이션과 적합한 보안 관리자 구현을 제공하는 PasswordSecurityManager 프로그램으로 구성되어 있다.

(The example consists of the FileIO application, and the PasswordSecurityManager program

  that provides the custom security manager implementation.)


 

FileIO 프로그램(The FileIO Program)

FileIO 프로그램은 간단한 사용자 인터페이스를 보여주고, 사용자에게 아무 문장이나 입력하도록 요구한다. 사용자가 “Click Me” 버튼을 클릭하면, 사용자가 입력한 문장은 사용자의 홈 디렉토리에 파일로 저장된다. 그리고 난 후 파일을 열어서 파일의 내용을 읽는다. 파일로부터 읽은 문장은 사용자에게 보여진다.

(The FileIO program displays a simple user interface and asks the end user to enter some text. When the end user clicks the Click Me button, the text is saved to a file in the end user's home directory, and a second file is opened and read. The text read from the second file is displayed to the end user.)

 

 

버튼 누르기 전 (Before Button Click)

 

버튼 누른 후  (After Button click)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

 

 

이 프로그램에 적합한 보안 관리자는 FileIO가 파일에 문장을 쓰거나 파일로부터 문장을 읽어 오기 전에

사용자에게 암호를 입력하도록 하게 한다. FileIO의 main 메서드는 PasswordSecurityManager 라는

이름의 적합한 보안 관리자를 만든다.

(The custom security manager for this program prompts the end user to enter a password before it allows FileIO to write text to or read text from a file. The main method of FileIO creates a custom security manager called PasswordSecurityManager.)

public static void main(String[] args){
  BufferedReader buffy = new BufferedReader(
      new InputStreamReader(System.in));
  try {
    System.setSecurityManager(
      new PasswordSecurityManager("pwd", buffy));
  } catch (SecurityException se) {
    System.err.println("SecurityManager already set!");
  }
 
 

PasswordSecurityManager 클래스(The PasswordSecurityManager Class)

PasswordSecurityManager 클래스는 이 보안 관리자가 생성될 때의 생성자에 의해 초기화 되는 두 개의 private 변수들을 선언한다. password 변수는 실제 암호를 가지고 있고, buffy 변수는 사용자가 입력한 암호를 저장하는 입력 버퍼이다.

(The PasswordSecurityManager class declares two private instance variables, which are initialized by the constructor when the custom security manager is installed. The password instance variable contains the actual password, and the buffy instance variable is an input buffer that stores the end user's password input.)

public class PasswordSecurityManager extends SecurityManager
{   private String password; private BufferedReader buffy;   public PasswordSecurityManager(String p, BufferedReader b){ super(); this.password = p; this.buffy = b; }

accessOK 메서드는 사용자에게 암호를 입력하라는 메시지를 보여준 후 그 암호를 확인하여 암호가

정확하면 true를 정확하지 않으면 false를 리턴한다.

(The accessOK method prompts the end user for a password, verifies the password,

  and returns true if the password is correct and false if it is not.)

private boolean accessOK() {
  int c;
  String response;
 
  System.out.println("Password, please:");
  try {
    response = buffy.readLine();
    if (response.equals(password))
      return true;
    else
      return false;
  } catch (IOException e) {
    return false;
  }
}

 

접근 권한 확인(Verify Access)

상위 클래스인 SecurityManager는 파일 시스템에 읽고 쓸 수 있는 접근 권한을 확인하기 위한 메서드를

제공한다. checkRead 와 checkWrite 메서드는 각각 String을 받을 수 있는 버전과 파일 디스크립터를

받을 수 있는 또 다른 버전을 가진다.

(The SecurityManager parent class provides methods to verify file system read and write access. The checkRead and checkWrite methods each have a version that accepts a String and another verion that accepts a file descriptor.)

 

이 예제인 FileIO 프로그램 String으로 디렉토리와 파일에 접근하기 때문에 예제를 간단하게 하기 위해서

단지 String 버전만 재정의 한다.

(This example overrides only the String versions to keep the example simple, and because the FileIO program accesses directories and files as Strings.)

public void checkRead(String filename) {
  if((filename.equals(File.separatorChar + "home" + 
        File.separatorChar + "monicap" + 
        File.separatorChar + "text2.txt"))){
  if(!accessOK()){
    super.checkRead(filename);
    throw new SecurityException("No Way!");
  } else {
    FilePermission perm = new FilePermission(
      File.separatorChar + "home" +
      File.separatorChar + "monicap" + 
      File.separatorChar + "text2.txt", "read");
      checkPermission(perm);
      }
   }
}
 
public void checkWrite(String filename) {
  if((filename.equals(File.separatorChar + "home" + 
                 File.separatorChar + "monicap" + 
                 File.separatorChar + "text.txt"))){
    if(!accessOK()){
      super.checkWrite(filename);
      throw new SecurityException("No Way!");
    } else {
      FilePermission perm = new FilePermission(
                File.separatorChar + "home" + 
                File.separatorChar + "monicap" + 
                File.separatorChar + "text.txt" , 
                "write");
            checkPermission(perm);
      }
    }
  }
}

checkWrite 메서드는 사용자의 입력이 출력 파일에 쓰여지기 전에 호출된다.

이것은 FileOutputStream 클래스가 SecurityManager.checkWrite 메서드를 처음에 호출하기 때문이다.(The checkWrite method is called before the end user input is written to the output file. This is because the FileOutputStream class calls SecurityManager.checkWrite first.)

 

사용자가 암호를 입력하면 SecurityManager.checkWrite는 패스가 /home/monicap/text.txt 인 파일을

테스트한다. 만약 암호가 정확하다면, checkWrite 메서드는 요구된 권한에 대한 인스턴스를 만들고

그것을 SecurityManager.checkPermission메서드에 넘김으로 접근 권한 확인을 수행한다.

 

이러한 확인 작업은 보안 관리자가 시스템과 사용자, 또는 프로그램에서 명시된 권한을 가진 정책 파일을

찾아 낸다면 성공할 것이다. 쓰는 작업이 한 번 완료 되는 동안 사용자는 두 번 이상 암호를 입력한다.

 

첫번째는 /home/monicap 디렉토리를 읽기 위한 것이고, 두번째는 text2.txt 파일을 읽기 위해서이다.

접근 권한 확인은 읽기 작업이 일어나기 전에 수행되어진다.(The custom implementation for SecurityManager.checkWrite tests for the pathname /home/monicap/text.txt, if true prompts the end user for the password. If the password is correct, the checkWrite method performs the access check by creating an instance of the required permission and passing it to the SecurityManager.checkPermission method. This check will succeed if the security manager finds a system, user, or program policy file with the specified permission. once the write operation completes, the end user is prompted for the password two more times. The first time to read the /home/monicap directory, and the second time to read the text2.txt file. An access check is performed before the read operation takes place.)

 

정책 파일(Policy File)

다음은 FileIO 프로그램이 읽고 쓰는 작업을 수행하기 위해서 필요한 정책 파일이다.

이 정책 파일은 또한 적합하게 구현된 보안 관리자에게 애플리케이션의 행동에 관한 이벤트 큐에 접근할 수

있는 권한과 경고 표시 없는 애플리케이션 윈도우를 보여줄 수 있는 권한을 부여한다.

(Here is the policy file the FileIO program needs for its read and write operations.

 It also grants permission to the custom security manager to access the event queue on

 behalf of the application and show the application window without the warning banner.)

grant {
  permission java.io.FilePermission 
        "${user.home}/text.txt", "write";
  permission java.util.PropertyPermission 
        "user.home", "read";
  permission java.io.FilePermission 
        "${user.home}/text2.txt", "read";
  permission java.awt.AWTPermission 
        "accessEventQueue";
  permission java.awt.AWTPermission 
        "showWindowWithoutWarningBanner";
};

FileIO 프로그램 실행하기(Run the FileIO Program)

다음은 정책 파일을 가진 FileIO 프로그램을 실행하는 방법이다

(Here is how to run the FileIO program with the policy file:)

 java -Djava.security.policy=polfile FileIO

 

참고할 수 있는 정보(Reference Information)

Appendix A: Security and Permissions은 이용 가능한 허가권을 설명하고 허가권을 부여한 결과를

설명한다. 이러한 정보를 사용하면 주어진 애플릿이나 애플리케이션이 성공적으로 수행되기 위해서

어떠한 권한들을 제한해야 하는지 알 수 있다. 또한 이러한 정보는 어떤 특별한 허가권이 악의가 있는

코드에 의해서 활용되어질 수 있는지 스스로를 교육시킬 수 있다.

(Appendix A: Security and Permissions describes the available permissions and explains the consequences of granting permissions. one way to use this information is to help you limit what permissions a given applet or application might need to successfully execute. Another way to use this information is to educate yourself on the ways in which a particular permission can be exploited by malicious code.)

 

Appendix B: Classes, Methods, and Permissions에서는 접근 권한을 확인하기 위해 호출되는 java.security.SecurityManager 메서드들과 각각 필요한 허가권과 보안 접근 확인을 수행하기 위해 구현된 자바 2 플랫폼 소프트웨어의 메서드들의 리스트를 제공한다.

(Appendix B: Classes, Methods, and Permissions provides lists of Java 2 platform software methods that are implemented to perform security access checks, the permission each requires, and the java.security.SecurityManager method called to perform the access check.)

 

당신은 자기 자신의 보안 관리자를 구현할 때 또는 보안 관련 작업들을 수행하는 추상 메서드들을 구현할 때 이러한 참고 사항들을 사용할 수 있다.

(You can use this reference to write your own security manager implementations or when you implement abstract methods that perform security-related tasks.)

 

Appendix C: SecurityManager Methods는 SecurityManager 메서드들에 의해서 확인되는 허가권들을 보여준다.

(Appendix C: SecurityManager Methods lists the permissions checked for by the 

 SecurityManager methods.)

 

 

 

 


 

 

 

  

애플릿은 제약사항이 있다.

크게 네트워크 접근과 파일 접근에 대한 제약이다.

 

특히 제약사항이 발생하면 아래와 같은 exception을 발생시킨다.

java.security.AccessControlException: access denied (java.io.FilePermission)

java.security.AccessControlException: access denied (java.net.SocketPermission)

 

그럴 경우는 애플릿이 실행되는 jre의 java.policy파일을 다음과 같이 추가하면 된다.

 

java.io.FilePermission 관련일 경우는

permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete, execute";

 

java.net.SocketPermission 관련일 경우는

permission java.net.SocketPermission "localhost:1024-", "listen,connect,accept,resolve";

 

아니면 모두를 허용하려면

permission java.security.AllPermission;

을 해주면 위의 두 개를 포함한 모든 제약을 제거해 준다

 

 

또한 다른 해결방법으로는 파일을 배포하는 방법인데

 

user.home디렉토리 보통은 C:\Documents and Settings\Administrator의 폴더에

.java.policy파일을 두면 된다.

 

.java.policy파일을 만드는 방법은 policytool을 이용하면 된다

 

 

더보기

 

1. "시작 → 실행" 버튼을 눌러서 실행창을 열어 cmd를 적고 엔터!

 


 

 


2. 도스 명령창에 policytool을 입력한후 엔터

 

 


3. policy 파일이 없다고 경고창이 뜨는데 무시하면 된다. (확인버튼 클릭)
   그 후 정책 항목 추가 버튼을 누른다.


 



 


4. 새로 뜬 창에서 사용 권한 추가를 누른다.

 

 




5. 사용 권한에서 AllPermission을 선택 후 "확인 → 완료" 버튼을 누른다.



 

6. "파일 → 다른 이름으로 저장" 버튼을 누른다.
   (저장위치는 변경하지 않고 파일이름만 .java.policy로 하여 저장한다.




7. 저장을 완료할경우 이런 창이 나오는데... "확인" 버튼을 누르고 정책도구 창을 종료한다.