java安全架构笔记

Share

    在现代的工作生活中,人们越来越依赖于网络获得的信息,大到公司的决策信息来源,小到我们说话的方式。作为一个标准的IPC(Information porvider source,源信息提供者),就必须确保信息的准确和安全。这样我们提出了一个话题--构建安全的网络信息基站。
    作为中国的程序员,大多数都是事后才采取安全信息的补上,并不是事先考虑到,这样往往給一个网站带来不小的损失。  
    现在能够参与构建信息基站的开发工具和开发语言也是越来越多,这里我们用JAVA来作为讨论的目标。
    java从始至终的理念是”Write One,Run Anywhere”(即一次编写,随处运行),它自诞生以来就不断的创造成功的案例。它提供了一种面向对象的编程语言和一个标准的运行环境,用于开发和实现安全的跨平台解决方案。这里,我们重点的探讨java的安全架构。
    以下是java 2中安全架构的核心元素:
    保护域(java.security.ProtectionDomain)在j2se中,默认情况下所有的本地java应用都可以像可信的应用一样不受限制的运行,也可以向applet和远程应用一样,給他配置访问控制策略。通常,我们将保护域分为应用域和系统域。所有受保护的外部资源,如文件系统、网络等,都只能通过系统域来访问,属于同一个执行线程的资源被视作为应用域。java.security.ProtectionDomain封装了这些保护域的特征。
   
    权限(Permission,java.security.Permission)简单的说,权限确定了一个程序是否能访问jvm的资源。常用的权限类有:
     通配权限:-java.security.AllPermission
      命名权限:-java.security.BasicPermission
      网络权限:-java.net.SocketPermission
      文件系统:-java.io.FilePermission
      属性:-java.lang.PropertyPermission
      运行时资源:-java.lang.RuntimePermission
      认证:-java.security.NetPermission
      图形资源:-java.awt.AWTPermission
    下面是一个如何用权限来保护访问对象的例子:
   

//Create the object that requires protection<br /> &nbsp; &nbsp; String protectedObj = "Hello World!";<br /> &nbsp; &nbsp; Guard myGuard = new propertyPermission("java.home","read");<br /> &nbsp; &nbsp; //Create the Guard<br /> &nbsp; &nbsp; GuardedObject gob = new GuardedObject(protectedObj,myGuard);<br /> &nbsp; &nbsp; //Get the Guard object<br /> &nbsp; &nbsp; try{<br /> &nbsp; &nbsp; &nbsp; &nbsp; Object o = gob.getObject();<br /> &nbsp; &nbsp; }catch(AccessControlException e){...}

    如果我们要像windows一样,赋予某个文件夹中某个文件只读的属性,可以在安全策略文件里面定义FilePermission,也可以这样实现:
   

grant{<br /> &nbsp; &nbsp; &nbsp; &nbsp; permission java.io.FilePermission "/tmp/test.file","read";<br /> &nbsp; &nbsp; };

   
    策略(Policy)java 2中的安全策略通过访问权限和权限集为所有的java代码定义了保护域。通常,所有的jvm都定义了安全机制,允许java安全策略文件来定义权限。java中,默认的系统级策略文件存放在$JAVA_HOME/lib/securuty/中。
    下面给出了一个策略配置文件,他首先为一个从”http://coresecuritypatterns.com/*”下载并由”javaguy”签名的JAR文件指定权限,然后授予该JAR文件读写访问/export/home/test/中所有文件的权限。
   

grand signedBy "javaguy",<br /> &nbsp; &nbsp; &nbsp; &nbsp; code base "http://coresecuritypatterns.com/*"{<br /> &nbsp; &nbsp; &nbsp; &nbsp; permission java.io.FilePermission &nbsp;"/export/home/test/","read,write";<br /> &nbsp; &nbsp; }

    也可以用命令行指定一个额外的策略文件:
    java -Djava.security.manager -Djava.security.policy==Mylocation/my.policy MyClass
    java 同时还提供了一个GUI的工具,这个大家经常用到,我都不多说了。({java_home}\bin\policy.exe)
   
    安全管理器(java.lang.SecurityManager)每一个java的应用都可以有自己的安全管理器,他是防范恶意攻击的主要安全卫士。安全管理器通过执行运行阶段检查和访问授权,以实施应用所需的安全策略,从而保护资源免受攻击。
    使用安全管理器:
   

SecurityManager mysmgr = System.getSecurityManager();<br /> &nbsp; &nbsp; if(mysmgr != null)<br /> &nbsp; &nbsp; &nbsp; &nbsp; mysmgr.checkWrite(name);

    使用安全管理器来实施访问控制:
   

//Before the security manager is enabled,this call is possible<br /> &nbsp; &nbsp; System.setProperty("java.version","Malicious:Delete");<br /> &nbsp; &nbsp; try{<br /> &nbsp; &nbsp; &nbsp; &nbsp; //Enable the security manager<br /> &nbsp; &nbsp; &nbsp; &nbsp; SecurityManager sm = new SecurityManager();<br /> &nbsp; &nbsp; &nbsp; &nbsp; System.setSecurityManager(sm);<br /> &nbsp; &nbsp; }catch(SecurityException e){<br /> &nbsp; &nbsp; &nbsp; &nbsp; ....<br /> &nbsp; &nbsp; }<br /> &nbsp; &nbsp; System.setProperty("java.version","Malicious:Delete");

    也可以用命令安装安全管理器:
    java -Djava.security.manager
   
    访问控制器(java.security.AccessController)访问控制器机制执行动态检查,并觉得允许还是拒绝对特定资源的访问。例如,我们要检查对文件系统中某个目录的读写权限,可以使用下列的代码:
   

try{<br /> &nbsp; &nbsp; &nbsp; AccessController.checkPermission(<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new FilePermission("/var/tmp/*","read,write"));<br /> &nbsp; &nbsp; }catch(SecurityException e){...}

    Codebase:用来指定类文件或者是jar文件的url位置
    Codesource:用来表示类所在的源URL和类签名使用的证书密钥
    例如:
   

URL codebase = null;<br /> &nbsp; &nbsp; try{<br /> &nbsp; &nbsp; &nbsp; codeBase = new URL("http://coresecuritypatterns.com/");<br /> &nbsp; &nbsp; }catch(...){....}<br /> &nbsp; &nbsp; <br /> &nbsp; &nbsp; CodeSource cs = new CodeSource(codeBase,null);<br /> &nbsp; &nbsp; PermissionCollection pcl = Policy.getPolicy().getPermission(cs);<br /> &nbsp; &nbsp; Enumeration num = pcl.elements();<br /> &nbsp; &nbsp; for(;num.hasMoreElements();){<br /> &nbsp; &nbsp; &nbsp; Permission p = (Permission)num.nextElement();<br /> &nbsp; &nbsp; &nbsp; System.out.println("Permission "+p);<br /> &nbsp; &nbsp; }

    下面是测试代码:
   

grant codebase "http://coresecuritypatterns.com/-"{<br /> &nbsp; &nbsp; &nbsp; permission java.util.PropertyPermission "*","read";<br /> &nbsp; &nbsp; };

    还可以执行下面的命令代替:
    java -Djava.security.policy==test.policy MyClass
             
    字节码验证器(Bytecode verifier):这个虽然是jvm不可缺少的一部分,但是我们很少用到,就略过。
   
    类加载器(ClassLoader)它负责加载类到jvm中,他通过命名空间来加载不同的类,进一步的加强了安全性。杜绝了不可信代码从可信代码处得到信息。它使用安全管理器来确定java应用的访问权限。
    下面給出了如何使用URLClassLoader加载目录中的类:
   

//Create a file object on the root of the<br /> &nbsp; &nbsp; //directory containing the class file<br /> &nbsp; &nbsp; File file = new File("/var/tmp/");<br /> &nbsp; &nbsp; try{<br /> &nbsp; &nbsp; &nbsp; //Convert File to a URL<br /> &nbsp; &nbsp; &nbsp; URL url = file.toURL();<br /> &nbsp; &nbsp; &nbsp; URL[] urls=new URL[]{url};<br /> &nbsp; &nbsp; &nbsp; <br /> &nbsp; &nbsp; &nbsp; //Create a new class loader with the direcetory<br /> &nbsp; &nbsp; &nbsp; ClassLoader myLoader = new URLClassLoader(urls);<br /> &nbsp; &nbsp; &nbsp; <br /> &nbsp; &nbsp; &nbsp; Class myclass = myLoader.loadClass("com.security.MySecureClass");<br /> &nbsp; &nbsp; }catch(...){...}

   
    密钥库(KeyStore)和密钥工具(Keytool)java 2平台提供了一个具有密码保护的数据库,用来存储可信的证书和密钥。keytool允许用户创建和管理自己用于认证服务和数字签名的公/私密钥以及相关的证书。以后有机会的话,会继续讨论下java密钥库和keytool的用法和这些工具如何促进java的安全。

                                                        作者:博爱老头  转载请注明出处