JAVA数字签名提升权限

    技术2023-03-29  21

    本文描述怎样通过数字签名提升java的访问权限,本文环境:

    os:Ubuntu9.10 64b

    Firefox:3.5.8 jre环境:JRE 1.6.0_18(64b)

    测试java代码和jsp页面代码如下:

    Java代码 public class TestApplet extends Applet {       private static final long serialVersionUID = 1L;       private void info(String msg) {           System.out.println(msg);       }       @Override      public void init() {           super.init();           readFile("Linux".equalsIgnoreCase(System.getProperty("os.name")) ? "/etc/hostname" : "c://boot.ini");       }       private void readFile(final String filePath) {           info("读取文件:" + filePath);           String text = AccessController.doPrivileged(new PrivilegedAction<String>() {               @Override              public String run() {                   StringBuilder buffer = new StringBuilder();                   BufferedReader reader = null;                   try {                       reader = new BufferedReader(new FileReader(filePath));                       while(reader.ready()) buffer.append(reader.readLine());                   } catch (Exception e) {                       throw new IllegalStateException(e);                   } finally {                       if (reader != null) {                           try {                               reader.close();                           } catch (IOException e) {                               e.printStackTrace();                           }                       }                   }                   return buffer.toString();               }           });           info("读取结果为:" + text);       }   }   public class TestApplet extends Applet { private static final long serialVersionUID = 1L; private void info(String msg) { System.out.println(msg); } @Override public void init() { super.init(); readFile("Linux".equalsIgnoreCase(System.getProperty("os.name")) ? "/etc/hostname" : "c://boot.ini"); } private void readFile(final String filePath) { info("读取文件:" + filePath); String text = AccessController.doPrivileged(new PrivilegedAction<String>() { @Override public String run() { StringBuilder buffer = new StringBuilder(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(filePath)); while(reader.ready()) buffer.append(reader.readLine()); } catch (Exception e) { throw new IllegalStateException(e); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); } }); info("读取结果为:" + text); } } Html代码 <%@ page language="java" pageEncoding="UTF-8"%>  <%   String path = request.getContextPath();   String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";   %>  <html>      <body>      <applet id="hh" alt="Applet" width="100" height="100"            code="org.skzr.TestApplet"            archive="skzr-applet-sign.jar"          codebase="<%=basePath %>demo" mayscript>      </applet>      </body>  </html>   <%@ page language="java" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <html> <body> <applet id="hh" alt="Applet" width="100" height="100" code="org.skzr.TestApplet" archive="skzr-applet-sign.jar" codebase="<%=basePath %>demo" mayscript> </applet> </body> </html>

     

    因为考虑到大家一般是windows 32位环境所以:导出时使用我的linux64下仅有的32位jdk:jdk1.6.0_14-32

    把以上类导出为包:skzr-applet.jar

    签名:(使用同一个32位jdk:jdk1.6.0_14-32)

    1 创建keystore:

      /prog/java/jdk1.6.0_14-32/bin/keytool -genkey -keystore skzr-applet.keystore -alias skzr-applet

    2 签名:

     /prog/java/jdk1.6.0_14-32/bin/jarsigner -keystore skzr-applet.keystore skzr-applet.jar skzr-applet

    把demo放入tomcat的webapps下,打开http://localhost:8080/demo/index.jsp测试

     

    index.jsp里面使用未签名包 :skzr-applet.jar在控制台可以发现异常:

    java.lang.IllegalStateException: java.security.AccessControlException: access denied (java.io.FilePermission /etc/hostname read),因为我的是linux所以读取此文件

    index.jsp里面使用已签名包 :skzr-applet-sign.jar在控制台可以发现正确读取了文件:下面是控制台输出:

    Html代码 读取文件:/etc/hostname   读取结果为:skzr   basic: Applet initialized   读取文件:/etc/hostname 读取结果为:skzr basic: Applet initialized

     至此权限提升完毕 ^ ^

    效果图:

    google chrome for linux firefox 3.5.8

    至于Windows下是一样的效果

     

     例子demo

    demo.zip 其中skzr-applet.jar未签名 skzr-applet-sign.jar是签名后的包

    总结:

    1 jre的策略文件不需要更改的 如果真的签名了,客户端加载运行jar时会出现询问是否信任此签名的提示的! 问题在于,你如果签名了整个applet jar那么每一次重新发布都需要重新签名,比较繁琐,好的办法是,把需要提升权限的打为一个jar,一般这个jar不会经常更改的,签名此jar就可以了,其他的(如界面UI)的jar就算修改了也不需要重新签名的 2 要点:需要提升权限的类一定要放入一个jar包,签名一次即可 3 注意执行需要权限的代码需要一个特殊的方法执行, AccessController.doPrivileged(...)如果信任此签名,将可以执行此代码

    最新回复(0)